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 SpCol Chris@49: //! @{ Chris@49: Chris@49: Chris@49: //! construct an empty column vector Chris@49: template Chris@49: inline Chris@49: SpCol::SpCol() Chris@49: : SpMat(0, 1) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a column vector with the specified number of elements Chris@49: template Chris@49: inline Chris@49: SpCol::SpCol(const uword in_n_elem) Chris@49: : SpMat(in_n_elem, 1) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: SpCol::SpCol(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_cols != 1), "SpCol::SpCol(): must have only one column"); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a column vector from specified text Chris@49: template Chris@49: inline Chris@49: SpCol::SpCol(const char* text) Chris@49: : SpMat(text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; Chris@49: Chris@49: arma_debug_check((SpMat::n_cols != 1), "SpCol::SpCol(): must have only one column"); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a column vector from specified text Chris@49: template Chris@49: inline Chris@49: const SpCol& Chris@49: SpCol::operator=(const char* text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: SpMat::init(std::string(text)); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a column vector from specified text Chris@49: template Chris@49: inline Chris@49: SpCol::SpCol(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) = 1; Chris@49: Chris@49: arma_debug_check((SpMat::n_cols != 1), "SpCol::SpCol(): must have only one column"); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! construct a column vector from specified text Chris@49: template Chris@49: inline Chris@49: const SpCol& Chris@49: SpCol::operator=(const std::string& text) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: SpMat::init(std::string(text)); Chris@49: Chris@49: return *this; Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: const SpCol& Chris@49: SpCol::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: SpCol::SpCol(const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; 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 SpCol& Chris@49: SpCol::operator=(const Base& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; 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: SpCol::SpCol(const SpBase& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; 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 SpCol& Chris@49: SpCol::operator=(const SpBase& X) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: access::rw(SpMat::vec_state) = 1; 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: SpCol::SpCol 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) = 1; 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: SpCol::row(const uword row_num) Chris@49: { Chris@49: arma_debug_check( (row_num >= SpMat::n_rows), "SpCol::row(): out of bounds" ); Chris@49: Chris@49: return SpMat::at(row_num, 0); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: eT Chris@49: SpCol::row(const uword row_num) const Chris@49: { Chris@49: arma_debug_check( (row_num >= SpMat::n_rows), "SpCol::row(): out of bounds" ); Chris@49: Chris@49: return SpMat::at(row_num, 0); Chris@49: } Chris@49: Chris@49: Chris@49: /* Chris@49: template Chris@49: arma_inline Chris@49: subview_col Chris@49: SpCol::rows(const uword in_row1, const uword in_row2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: Chris@49: return subview_col(*this, 0, in_row1, subview_n_rows); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const subview_col Chris@49: SpCol::rows(const uword in_row1, const uword in_row2) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat::n_rows) ), "Col::rows(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: Chris@49: return subview_col(*this, 0, in_row1, subview_n_rows); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: subview_col Chris@49: SpCol::subvec(const uword in_row1, const uword in_row2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: Chris@49: return subview_col(*this, 0, in_row1, subview_n_rows); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const subview_col Chris@49: SpCol::subvec(const uword in_row1, const uword in_row2) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( ( (in_row1 > in_row2) || (in_row2 >= SpMat::n_rows) ), "Col::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: const uword subview_n_rows = in_row2 - in_row1 + 1; Chris@49: Chris@49: return subview_col(*this, 0, in_row1, subview_n_rows); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: subview_col Chris@49: SpCol::subvec(const span& row_span) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool row_all = row_span.whole; Chris@49: Chris@49: const uword local_n_rows = SpMat::n_rows; Chris@49: Chris@49: const uword in_row1 = row_all ? 0 : row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; Chris@49: Chris@49: arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: return subview_col(*this, 0, in_row1, subvec_n_rows); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: arma_inline Chris@49: const subview_col Chris@49: SpCol::subvec(const span& row_span) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: const bool row_all = row_span.whole; Chris@49: Chris@49: const uword local_n_rows = SpMat::n_rows; Chris@49: Chris@49: const uword in_row1 = row_all ? 0 : row_span.a; Chris@49: const uword in_row2 = row_span.b; Chris@49: const uword subvec_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1; Chris@49: Chris@49: arma_debug_check( ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) ), "Col::subvec(): indices out of bounds or incorrectly used"); Chris@49: Chris@49: return subview_col(*this, 0, in_row1, subvec_n_rows); Chris@49: } Chris@49: */ Chris@49: Chris@49: Chris@49: //! remove specified row Chris@49: template Chris@49: inline Chris@49: void Chris@49: SpCol::shed_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( row_num >= SpMat::n_rows, "SpCol::shed_row(): out of bounds"); Chris@49: Chris@49: shed_rows(row_num, row_num); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: //! remove specified rows Chris@49: template Chris@49: inline Chris@49: void Chris@49: SpCol::shed_rows(const uword in_row1, const uword in_row2) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check Chris@49: ( Chris@49: (in_row1 > in_row2) || (in_row2 >= SpMat::n_rows), Chris@49: "SpCol::shed_rows(): indices out of bounds or incorrectly used" Chris@49: ); Chris@49: Chris@49: const uword diff = (in_row2 - in_row1 + 1); Chris@49: Chris@49: // This is easy because everything is in one column. Chris@49: uword start = 0, end = 0; Chris@49: bool start_found = false, end_found = false; Chris@49: for(uword i = 0; i < SpMat::n_nonzero; ++i) Chris@49: { Chris@49: // Start position found? Chris@49: if (SpMat::row_indices[i] >= in_row1 && !start_found) Chris@49: { Chris@49: start = i; Chris@49: start_found = true; Chris@49: } Chris@49: Chris@49: // End position found? Chris@49: if (SpMat::row_indices[i] > in_row2) Chris@49: { Chris@49: end = i; Chris@49: end_found = true; Chris@49: break; Chris@49: } Chris@49: } Chris@49: Chris@49: if (!end_found) Chris@49: { Chris@49: end = SpMat::n_nonzero; Chris@49: } Chris@49: Chris@49: // Now we can make the copy. 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 before the section we are dropping (if it exists). 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 after the section we are dropping (if it exists). 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: arrayops::inplace_minus(new_row_indices + start, diff, (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: access::rw(SpMat::col_ptrs[1]) -= elem_diff; Chris@49: } Chris@49: Chris@49: access::rw(SpMat::n_rows) -= diff; Chris@49: access::rw(SpMat::n_elem) -= diff; Chris@49: Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: // //! insert N rows at the specified row position, Chris@49: // //! optionally setting the elements of the inserted rows to zero Chris@49: // template Chris@49: // inline Chris@49: // void Chris@49: // SpCol::insert_rows(const uword row_num, const uword N, const bool set_to_zero) Chris@49: // { Chris@49: // arma_extra_debug_sigprint(); Chris@49: // Chris@49: // arma_debug_check(set_to_zero == false, "SpCol::insert_rows(): cannot set nonzero values"); Chris@49: // Chris@49: // arma_debug_check((row_num > SpMat::n_rows), "SpCol::insert_rows(): out of bounds"); Chris@49: // Chris@49: // for(uword row = 0; row < SpMat::n_rows; ++row) Chris@49: // { Chris@49: // if (SpMat::row_indices[row] >= row_num) Chris@49: // { Chris@49: // access::rw(SpMat::row_indices[row]) += N; Chris@49: // } Chris@49: // } Chris@49: // Chris@49: // access::rw(SpMat::n_rows) += 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 row position; Chris@49: // //! the given object must have one column Chris@49: // template Chris@49: // template Chris@49: // inline Chris@49: // void Chris@49: // SpCol::insert_rows(const uword row_num, const Base& X) Chris@49: // { Chris@49: // arma_extra_debug_sigprint(); Chris@49: // Chris@49: // SpMat::insert_rows(row_num, X); Chris@49: // } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpCol::row_iterator Chris@49: SpCol::begin_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= SpMat::n_rows), "begin_row(): index out of bounds"); Chris@49: Chris@49: return row_iterator(*this, row_num, 0); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpCol::const_row_iterator Chris@49: SpCol::begin_row(const uword row_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= SpMat::n_rows), "begin_row(): index out of bounds"); Chris@49: Chris@49: return const_row_iterator(*this, row_num, 0); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpCol::row_iterator Chris@49: SpCol::end_row(const uword row_num) Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= SpMat::n_rows), "end_row(): index out of bounds"); Chris@49: Chris@49: return row_iterator(*this, row_num + 1, 0); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: template Chris@49: inline Chris@49: typename SpCol::const_row_iterator Chris@49: SpCol::end_row(const uword row_num) const Chris@49: { Chris@49: arma_extra_debug_sigprint(); Chris@49: Chris@49: arma_debug_check( (row_num >= SpMat::n_rows), "end_row(): index out of bounds"); Chris@49: Chris@49: return const_row_iterator(*this, row_num + 1, 0); Chris@49: } Chris@49: Chris@49: Chris@49: Chris@49: #ifdef ARMA_EXTRA_SPCOL_MEAT Chris@49: #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPCOL_MEAT) Chris@49: #endif Chris@49: Chris@49: Chris@49: Chris@49: //! @}