| SpMat_bones.hpp | | SpMat_bones.hpp | |
| | | | |
| skipping to change at line 50 | | skipping to change at line 50 | |
| /** | | /** | |
| * The memory used to store the values of the matrix. | | * The memory used to store the values of the matrix. | |
| * In accordance with the CSC format, this stores only the actual values. | | * In accordance with the CSC format, this stores only the actual values. | |
| * The correct locations of the values are assembled from the row indices | | * The correct locations of the values are assembled from the row indices | |
| * and the column pointers. | | * and the column pointers. | |
| */ | | */ | |
| const eT* const values; | | const eT* const values; | |
| | | | |
| /** | | /** | |
| * The row indices of each value. row_indices[i] is the row of values[i]
. | | * The row indices of each value. row_indices[i] is the row of values[i]
. | |
|
| | | * The length of this array is n_nonzero + 1; the final value ensures the | |
| | | * integrity of iterators. | |
| */ | | */ | |
| const uword* const row_indices; | | const uword* const row_indices; | |
| | | | |
| /** | | /** | |
| * The column pointers. This stores the index of the first item in colum
n i. | | * The column pointers. This stores the index of the first item in colum
n i. | |
| * That is, values[col_ptrs[i]] is the first value in column i, and it is
in | | * That is, values[col_ptrs[i]] is the first value in column i, and it is
in | |
| * row row_indices[col_ptrs[i]]. | | * row row_indices[col_ptrs[i]]. | |
| */ | | */ | |
| const uword* const col_ptrs; | | const uword* const col_ptrs; | |
| | | | |
| | | | |
| skipping to change at line 302 | | skipping to change at line 304 | |
| // Iterator base provides comparison operators but not the actual logic o
n how | | // Iterator base provides comparison operators but not the actual logic o
n how | |
| // to iterate. The validity of the position is not checked (that is left
up | | // to iterate. The validity of the position is not checked (that is left
up | |
| // to the user). | | // to the user). | |
| class iterator_base | | class iterator_base | |
| { | | { | |
| public: | | public: | |
| | | | |
| inline iterator_base(const SpMat& in_M); | | inline iterator_base(const SpMat& in_M); | |
| inline iterator_base(const SpMat& in_M, const uword col, const uword po
s); | | inline iterator_base(const SpMat& in_M, const uword col, const uword po
s); | |
| | | | |
|
| inline eT operator*() const; | | inline arma_hot eT operator*() const; | |
| | | | |
|
| inline bool operator==(const iterator_base& rhs) const; | | inline arma_hot bool operator==(const iterator_base& rhs) const; | |
| inline bool operator!=(const iterator_base& rhs) const; | | inline arma_hot bool operator!=(const iterator_base& rhs) const; | |
| | | | |
|
| inline bool operator==(const typename SpSubview<eT>::iterator_base& rhs | | inline arma_hot bool operator==(const typename SpSubview<eT>::iterator_ | |
| ) const; | | base& rhs) const; | |
| inline bool operator!=(const typename SpSubview<eT>::iterator_base& rhs | | inline arma_hot bool operator!=(const typename SpSubview<eT>::iterator_ | |
| ) const; | | base& rhs) const; | |
| | | | |
| // Don't hold location internally; call "dummy" methods to get that inf
ormation. | | // Don't hold location internally; call "dummy" methods to get that inf
ormation. | |
| arma_inline uword row() const { return M.row_indices[internal_pos]; } | | arma_inline uword row() const { return M.row_indices[internal_pos]; } | |
| arma_inline uword col() const { return internal_col; } | | arma_inline uword col() const { return internal_col; } | |
| arma_inline uword pos() const { return internal_pos; } | | arma_inline uword pos() const { return internal_pos; } | |
| | | | |
| arma_aligned const SpMat& M; | | arma_aligned const SpMat& M; | |
| arma_aligned uword internal_col; | | arma_aligned uword internal_col; | |
| arma_aligned uword internal_pos; | | arma_aligned uword internal_pos; | |
| }; | | }; | |
| | | | |
| class const_iterator : public iterator_base | | class const_iterator : public iterator_base | |
| { | | { | |
| public: | | public: | |
| | | | |
| inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Ass
umes initial_pos is valid. | | inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Ass
umes initial_pos is valid. | |
| //! Once initialized, will be at the first nonzero value after the give
n position (using forward columnwise traversal). | | //! Once initialized, will be at the first nonzero value after the give
n position (using forward columnwise traversal). | |
| inline const_iterator(const SpMat& in_M, uword in_row, uword in_col); | | inline const_iterator(const SpMat& in_M, uword in_row, uword in_col); | |
|
| | | //! If you know the exact position of the iterator. in_row is a dummy | |
| | | argument. | |
| | | inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uw | |
| | | ord in_pos); | |
| inline const_iterator(const const_iterator& other); | | inline const_iterator(const const_iterator& other); | |
| | | | |
|
| inline const_iterator& operator++(); | | inline arma_hot const_iterator& operator++(); | |
| inline void operator++(int); | | inline arma_hot void operator++(int); | |
| | | | |
|
| inline const_iterator& operator--(); | | inline arma_hot const_iterator& operator--(); | |
| inline void operator--(int); | | inline arma_hot void operator--(int); | |
| }; | | }; | |
| | | | |
| /** | | /** | |
| * So that we can iterate over nonzero values, we need an iterator | | * So that we can iterate over nonzero values, we need an iterator | |
| * implementation. This can't be as simple as Mat's, which is just a poi
nter | | * implementation. This can't be as simple as Mat's, which is just a poi
nter | |
| * to an eT. If a value is set to 0 using this iterator, the iterator is
no | | * to an eT. If a value is set to 0 using this iterator, the iterator is
no | |
| * longer valid! | | * longer valid! | |
| */ | | */ | |
| class iterator : public const_iterator | | class iterator : public const_iterator | |
| { | | { | |
| public: | | public: | |
| | | | |
| inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in
_M, initial_pos) { } | | inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in
_M, initial_pos) { } | |
| inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterat
or(in_M, in_row, in_col) { } | | inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterat
or(in_M, in_row, in_col) { } | |
|
| | | inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos)
: const_iterator(in_M, in_row, in_col, in_pos) { } | |
| inline iterator(const const_iterator& other) : const_iterator(other) {
} | | inline iterator(const const_iterator& other) : const_iterator(other) {
} | |
| | | | |
|
| inline SpValProxy<SpMat<eT> > operator*(); | | inline arma_hot SpValProxy<SpMat<eT> > operator*(); | |
| | | | |
| // overloads needed for return type correctness | | // overloads needed for return type correctness | |
|
| inline iterator& operator++(); | | inline arma_hot iterator& operator++(); | |
| inline void operator++(int); | | inline arma_hot void operator++(int); | |
| | | | |
|
| inline iterator& operator--(); | | inline arma_hot iterator& operator--(); | |
| inline void operator--(int); | | inline arma_hot void operator--(int); | |
| }; | | }; | |
| | | | |
| class const_row_iterator : public iterator_base | | class const_row_iterator : public iterator_base | |
| { | | { | |
| public: | | public: | |
| | | | |
| inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0); | | inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0); | |
| //! Once initialized, will be at the first nonzero value after the give
n position (using forward row-wise traversal). | | //! Once initialized, will be at the first nonzero value after the give
n position (using forward row-wise traversal). | |
| inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col
); | | inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col
); | |
| inline const_row_iterator(const const_row_iterator& other); | | inline const_row_iterator(const const_row_iterator& other); | |
| | | | |
|
| inline const_row_iterator& operator++(); | | inline arma_hot const_row_iterator& operator++(); | |
| inline void operator++(int); | | inline arma_hot void operator++(int); | |
| | | | |
|
| inline const_row_iterator& operator--(); | | inline arma_hot const_row_iterator& operator--(); | |
| inline void operator--(int); | | inline arma_hot void operator--(int); | |
| | | | |
| uword internal_row; // Hold row internally because we use internal_pos
differently. | | uword internal_row; // Hold row internally because we use internal_pos
differently. | |
| uword actual_pos; // Actual position in matrix. | | uword actual_pos; // Actual position in matrix. | |
| | | | |
| arma_inline eT operator*() const { return iterator_base::M.values[actua
l_pos]; } | | arma_inline eT operator*() const { return iterator_base::M.values[actua
l_pos]; } | |
| | | | |
| arma_inline uword row() const { return internal_row; } | | arma_inline uword row() const { return internal_row; } | |
| }; | | }; | |
| | | | |
| class row_iterator : public const_row_iterator | | class row_iterator : public const_row_iterator | |
| { | | { | |
| public: | | public: | |
| | | | |
| inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_ite
rator(in_M, initial_pos) { } | | inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_ite
rator(in_M, initial_pos) { } | |
| //! Once initialized, will be at the first nonzero value after the give
n position (using forward row-wise traversal). | | //! Once initialized, will be at the first nonzero value after the give
n position (using forward row-wise traversal). | |
| inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_ro
w_iterator(in_M, in_row, in_col) { } | | inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_ro
w_iterator(in_M, in_row, in_col) { } | |
| inline row_iterator(const row_iterator& other) : const_row_iterator(oth
er) { } | | inline row_iterator(const row_iterator& other) : const_row_iterator(oth
er) { } | |
| | | | |
|
| inline SpValProxy<SpMat<eT> > operator*(); | | inline arma_hot SpValProxy<SpMat<eT> > operator*(); | |
| | | | |
| // overloads required for return type correctness | | // overloads required for return type correctness | |
|
| inline row_iterator& operator++(); | | inline arma_hot row_iterator& operator++(); | |
| inline void operator++(int); | | inline arma_hot void operator++(int); | |
| | | | |
|
| inline row_iterator& operator--(); | | inline arma_hot row_iterator& operator--(); | |
| inline void operator--(int); | | inline arma_hot void operator--(int); | |
| }; | | }; | |
| | | | |
| inline iterator begin(); | | inline iterator begin(); | |
| inline const_iterator begin() const; | | inline const_iterator begin() const; | |
| | | | |
|
| inline iterator end(); | | inline iterator end(); | |
| inline const_iterator end() const; | | inline const_iterator end() const; | |
| | | | |
| inline iterator begin_col(const uword col_num); | | inline iterator begin_col(const uword col_num); | |
| inline const_iterator begin_col(const uword col_num) const; | | inline const_iterator begin_col(const uword col_num) const; | |
| | | | |
| inline iterator end_col(const uword col_num); | | inline iterator end_col(const uword col_num); | |
| inline const_iterator end_col(const uword col_num) const; | | inline const_iterator end_col(const uword col_num) const; | |
| | | | |
| inline row_iterator begin_row(const uword row_num = 0); | | inline row_iterator begin_row(const uword row_num = 0); | |
| inline const_row_iterator begin_row(const uword row_num = 0) const; | | inline const_row_iterator begin_row(const uword row_num = 0) const; | |
| | | | |
| | | | |
End of changes. 17 change blocks. |
| 27 lines changed or deleted | | 34 lines changed or added | |
|
| SpMat_iterators_meat.hpp | | SpMat_iterators_meat.hpp | |
| | | | |
| skipping to change at line 43 | | skipping to change at line 43 | |
| SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword
col, const uword pos) | | SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword
col, const uword pos) | |
| : M(in_M) | | : M(in_M) | |
| , internal_col(col) | | , internal_col(col) | |
| , internal_pos(pos) | | , internal_pos(pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| eT | | eT | |
| SpMat<eT>::iterator_base::operator*() const | | SpMat<eT>::iterator_base::operator*() const | |
| { | | { | |
| return M.values[internal_pos]; | | return M.values[internal_pos]; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| bool | | bool | |
| SpMat<eT>::iterator_base::operator==(const iterator_base& rhs) const | | SpMat<eT>::iterator_base::operator==(const iterator_base& rhs) const | |
| { | | { | |
| return (rhs.row() == row()) && (rhs.col() == internal_col); | | return (rhs.row() == row()) && (rhs.col() == internal_col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| bool | | bool | |
| SpMat<eT>::iterator_base::operator!=(const iterator_base& rhs) const | | SpMat<eT>::iterator_base::operator!=(const iterator_base& rhs) const | |
| { | | { | |
| return (rhs.row() != row()) || (rhs.col() != internal_col); | | return (rhs.row() != row()) || (rhs.col() != internal_col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| bool | | bool | |
| SpMat<eT>::iterator_base::operator==(const typename SpSubview<eT>::iterator
_base& rhs) const | | SpMat<eT>::iterator_base::operator==(const typename SpSubview<eT>::iterator
_base& rhs) const | |
| { | | { | |
| return (rhs.row() == row()) && (rhs.col() == internal_col); | | return (rhs.row() == row()) && (rhs.col() == internal_col); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| bool | | bool | |
| SpMat<eT>::iterator_base::operator!=(const typename SpSubview<eT>::iterator
_base& rhs) const | | SpMat<eT>::iterator_base::operator!=(const typename SpSubview<eT>::iterator
_base& rhs) const | |
| { | | { | |
| return (rhs.row() != row()) || (rhs.col() != internal_col); | | return (rhs.row() != row()) || (rhs.col() != internal_col); | |
| } | | } | |
| | | | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| // SpMat::const_iterator implementation
// | | // SpMat::const_iterator implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword init
ial_pos) | | SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword init
ial_pos) | |
| : iterator_base(in_M, 0, initial_pos) | | : iterator_base(in_M, 0, initial_pos) | |
| { | | { | |
|
| | | // Corner case for empty matrices. | |
| | | if(in_M.n_nonzero == 0) | |
| | | { | |
| | | iterator_base::internal_col = in_M.n_cols; | |
| | | return; | |
| | | } | |
| | | | |
| // Determine which column we should be in. | | // Determine which column we should be in. | |
| while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= itera
tor_base::internal_pos) | | while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= itera
tor_base::internal_pos) | |
| { | | { | |
| iterator_base::internal_col++; | | iterator_base::internal_col++; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword in_r
ow, uword in_col) | | SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword in_r
ow, uword in_col) | |
| | | | |
| skipping to change at line 120 | | skipping to change at line 132 | |
| | | | |
| // Now we have to get to the right row. | | // Now we have to get to the right row. | |
| while((iterator_base::M.row_indices[iterator_base::internal_pos] < in_row
) && (iterator_base::internal_col == in_col)) | | while((iterator_base::M.row_indices[iterator_base::internal_pos] < in_row
) && (iterator_base::internal_col == in_col)) | |
| { | | { | |
| ++(*this); // Increment iterator. | | ++(*this); // Increment iterator. | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, const uwor | |
| | | d /* in_row */, const uword in_col, const uword in_pos) | |
| | | : iterator_base(in_M, in_col, in_pos) | |
| | | { | |
| | | // Nothing to do. | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| SpMat<eT>::const_iterator::const_iterator(const typename SpMat<eT>::const_i
terator& other) | | SpMat<eT>::const_iterator::const_iterator(const typename SpMat<eT>::const_i
terator& other) | |
| : iterator_base(other.M, other.internal_col, other.internal_pos) | | : iterator_base(other.M, other.internal_col, other.internal_pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::const_iterator& | | typename SpMat<eT>::const_iterator& | |
| SpMat<eT>::const_iterator::operator++() | | SpMat<eT>::const_iterator::operator++() | |
| { | | { | |
| ++iterator_base::internal_pos; | | ++iterator_base::internal_pos; | |
| | | | |
| if (iterator_base::internal_pos == iterator_base::M.n_nonzero) | | if (iterator_base::internal_pos == iterator_base::M.n_nonzero) | |
| { | | { | |
| iterator_base::internal_col = iterator_base::M.n_cols; | | iterator_base::internal_col = iterator_base::M.n_cols; | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 150 | | skipping to change at line 171 | |
| while (iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iter
ator_base::internal_pos) | | while (iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iter
ator_base::internal_pos) | |
| { | | { | |
| ++iterator_base::internal_col; | | ++iterator_base::internal_col; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::const_iterator::operator++(int) | | SpMat<eT>::const_iterator::operator++(int) | |
| { | | { | |
| ++(*this); | | ++(*this); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::const_iterator& | | typename SpMat<eT>::const_iterator& | |
| SpMat<eT>::const_iterator::operator--() | | SpMat<eT>::const_iterator::operator--() | |
| { | | { | |
|
| iterator_base::M.print("M"); | | //iterator_base::M.print("M"); | |
| | | | |
| // printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, ite
rator_base::internal_col, iterator_base::row()); | | // printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, ite
rator_base::internal_col, iterator_base::row()); | |
| | | | |
| --iterator_base::internal_pos; | | --iterator_base::internal_pos; | |
| | | | |
| // printf("now pos %d\n", iterator_base::internal_pos); | | // printf("now pos %d\n", iterator_base::internal_pos); | |
| | | | |
| // First, see if we moved back a column. | | // First, see if we moved back a column. | |
| while (iterator_base::internal_pos < iterator_base::M.col_ptrs[iterator_b
ase::internal_col]) | | while (iterator_base::internal_pos < iterator_base::M.col_ptrs[iterator_b
ase::internal_col]) | |
| { | | { | |
| // printf("colptr %d (col %d)\n", iterator_base::M.col_ptrs[iterator_ba
se::internal_col], iterator_base::internal_col); | | // printf("colptr %d (col %d)\n", iterator_base::M.col_ptrs[iterator_ba
se::internal_col], iterator_base::internal_col); | |
| | | | |
| --iterator_base::internal_col; | | --iterator_base::internal_col; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::const_iterator::operator--(int) | | SpMat<eT>::const_iterator::operator--(int) | |
| { | | { | |
| --(*this); | | --(*this); | |
| } | | } | |
| | | | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| // SpMat::iterator implementation
// | | // SpMat::iterator implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| SpValProxy<SpMat<eT> > | | SpValProxy<SpMat<eT> > | |
| SpMat<eT>::iterator::operator*() | | SpMat<eT>::iterator::operator*() | |
| { | | { | |
| return SpValProxy<SpMat<eT> >( | | return SpValProxy<SpMat<eT> >( | |
| iterator_base::M.row_indices[iterator_base::internal_pos], | | iterator_base::M.row_indices[iterator_base::internal_pos], | |
| iterator_base::internal_col, | | iterator_base::internal_col, | |
| access::rw(iterator_base::M), | | access::rw(iterator_base::M), | |
| &access::rw(iterator_base::M.values[iterator_base::internal_pos])); | | &access::rw(iterator_base::M.values[iterator_base::internal_pos])); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::iterator& | | typename SpMat<eT>::iterator& | |
| SpMat<eT>::iterator::operator++() | | SpMat<eT>::iterator::operator++() | |
| { | | { | |
| const_iterator::operator++(); | | const_iterator::operator++(); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::iterator::operator++(int) | | SpMat<eT>::iterator::operator++(int) | |
| { | | { | |
| const_iterator::operator++(); | | const_iterator::operator++(); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::iterator& | | typename SpMat<eT>::iterator& | |
| SpMat<eT>::iterator::operator--() | | SpMat<eT>::iterator::operator--() | |
| { | | { | |
| const_iterator::operator--(); | | const_iterator::operator--(); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::iterator::operator--(int) | | SpMat<eT>::iterator::operator--(int) | |
| { | | { | |
| const_iterator::operator--(); | | const_iterator::operator--(); | |
| } | | } | |
| | | | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| // SpMat::const_row_iterator implementation
// | | // SpMat::const_row_iterator implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| /** | | /** | |
| * Initialize the const_row_iterator. | | * Initialize the const_row_iterator. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uw
ord initial_pos) | | SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uw
ord initial_pos) | |
| : iterator_base(in_M, 0, initial_pos) | | : iterator_base(in_M, 0, initial_pos) | |
| , internal_row(0) | | , internal_row(0) | |
| , actual_pos(0) | | , actual_pos(0) | |
| { | | { | |
|
| | | // Corner case for empty matrix. | |
| | | if(in_M.n_nonzero == 0) | |
| | | { | |
| | | iterator_base::internal_col = in_M.n_cols; | |
| | | return; | |
| | | } | |
| | | | |
| // We don't count zeroes in our position count, so we have to find the no
nzero | | // We don't count zeroes in our position count, so we have to find the no
nzero | |
| // value corresponding to the given initial position. We assume initial_
pos | | // value corresponding to the given initial position. We assume initial_
pos | |
| // is valid. | | // is valid. | |
| | | | |
| // This is irritating because we don't know where the elements are in eac
h | | // This is irritating because we don't know where the elements are in eac
h | |
| // row. What we will do is loop across all columns looking for elements
in | | // row. What we will do is loop across all columns looking for elements
in | |
| // row 0 (and add to our sum), then in row 1, and so forth, until we get
to | | // row 0 (and add to our sum), then in row 1, and so forth, until we get
to | |
| // the desired position. | | // the desired position. | |
| uword cur_pos = -1; | | uword cur_pos = -1; | |
| uword cur_row = 0; | | uword cur_row = 0; | |
| | | | |
| skipping to change at line 343 | | skipping to change at line 379 | |
| , actual_pos(other.actual_pos) | | , actual_pos(other.actual_pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Increment the row_iterator. | | * Increment the row_iterator. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::const_row_iterator& | | typename SpMat<eT>::const_row_iterator& | |
| SpMat<eT>::const_row_iterator::operator++() | | SpMat<eT>::const_row_iterator::operator++() | |
| { | | { | |
| // We just need to find the next nonzero element. | | // We just need to find the next nonzero element. | |
| iterator_base::internal_pos++; | | iterator_base::internal_pos++; | |
| | | | |
| if(iterator_base::internal_pos == iterator_base::M.n_nonzero) | | if(iterator_base::internal_pos == iterator_base::M.n_nonzero) | |
| { | | { | |
| internal_row = iterator_base::M.n_rows; | | internal_row = iterator_base::M.n_rows; | |
| iterator_base::internal_col = 0; | | iterator_base::internal_col = 0; | |
| | | | |
| skipping to change at line 392 | | skipping to change at line 429 | |
| } | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Increment the row_iterator (but do not return anything. | | * Increment the row_iterator (but do not return anything. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::const_row_iterator::operator++(int) | | SpMat<eT>::const_row_iterator::operator++(int) | |
| { | | { | |
| ++(*this); | | ++(*this); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Decrement the row_iterator. | | * Decrement the row_iterator. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::const_row_iterator& | | typename SpMat<eT>::const_row_iterator& | |
| SpMat<eT>::const_row_iterator::operator--() | | SpMat<eT>::const_row_iterator::operator--() | |
| { | | { | |
| iterator_base::internal_pos--; | | iterator_base::internal_pos--; | |
| | | | |
| // We have to search backwards. | | // We have to search backwards. | |
| uword cur_col = iterator_base::internal_col; | | uword cur_col = iterator_base::internal_col; | |
| uword cur_row = internal_row; | | uword cur_row = internal_row; | |
| | | | |
| while (true) // This loop is terminated from the inside. | | while (true) // This loop is terminated from the inside. | |
| | | | |
| skipping to change at line 442 | | skipping to change at line 481 | |
| } | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Decrement the row_iterator. | | * Decrement the row_iterator. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::const_row_iterator::operator--(int) | | SpMat<eT>::const_row_iterator::operator--(int) | |
| { | | { | |
| --(*this); | | --(*this); | |
| } | | } | |
| | | | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| // SpMat::row_iterator implementation
// | | // SpMat::row_iterator implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| SpValProxy<SpMat<eT> > | | SpValProxy<SpMat<eT> > | |
| SpMat<eT>::row_iterator::operator*() | | SpMat<eT>::row_iterator::operator*() | |
| { | | { | |
| return SpValProxy<SpMat<eT> >( | | return SpValProxy<SpMat<eT> >( | |
| const_row_iterator::internal_row, | | const_row_iterator::internal_row, | |
| iterator_base::internal_col, | | iterator_base::internal_col, | |
| access::rw(iterator_base::M), | | access::rw(iterator_base::M), | |
| &access::rw(iterator_base::M.values[const_row_iterator::actual_pos])); | | &access::rw(iterator_base::M.values[const_row_iterator::actual_pos])); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::row_iterator& | | typename SpMat<eT>::row_iterator& | |
| SpMat<eT>::row_iterator::operator++() | | SpMat<eT>::row_iterator::operator++() | |
| { | | { | |
| const_row_iterator::operator++(); | | const_row_iterator::operator++(); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::row_iterator::operator++(int) | | SpMat<eT>::row_iterator::operator++(int) | |
| { | | { | |
| const_row_iterator::operator++(); | | const_row_iterator::operator++(); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| typename SpMat<eT>::row_iterator& | | typename SpMat<eT>::row_iterator& | |
| SpMat<eT>::row_iterator::operator--() | | SpMat<eT>::row_iterator::operator--() | |
| { | | { | |
| const_row_iterator::operator--(); | | const_row_iterator::operator--(); | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_hot | |
| void | | void | |
| SpMat<eT>::row_iterator::operator--(int) | | SpMat<eT>::row_iterator::operator--(int) | |
| { | | { | |
| const_row_iterator::operator--(); | | const_row_iterator::operator--(); | |
| } | | } | |
| | | | |
| //! @} | | //! @} | |
| | | | |
End of changes. 27 change blocks. |
| 1 lines changed or deleted | | 47 lines changed or added | |
|
| SpMat_meat.hpp | | SpMat_meat.hpp | |
| | | | |
| skipping to change at line 28 | | skipping to change at line 28 | |
| * Initialize a sparse matrix with size 0x0 (empty). | | * Initialize a sparse matrix with size 0x0 (empty). | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::SpMat() | | SpMat<eT>::SpMat() | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
|
| , values(NULL) | | , values(memory::acquire_chunked<eT>(1)) | |
| , row_indices(NULL) | | , row_indices(memory::acquire_chunked<uword>(1)) | |
| , col_ptrs(memory::acquire<uword>(1)) | | , col_ptrs(memory::acquire<uword>(1)) | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
|
| | | access::rw(values[0]) = 0; | |
| | | access::rw(row_indices[0]) = 0; | |
| | | | |
| access::rw(col_ptrs[0]) = 0; // No elements. | | access::rw(col_ptrs[0]) = 0; // No elements. | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Clean up the memory of a sparse matrix and destruct it. | | * Clean up the memory of a sparse matrix and destruct it. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::~SpMat() | | SpMat<eT>::~SpMat() | |
| { | | { | |
| | | | |
| skipping to change at line 243 | | skipping to change at line 246 | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator+=(const SpMat<eT>& x) | | SpMat<eT>::operator+=(const SpMat<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition
"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition
"); | |
| | | | |
| // Iterate over nonzero values of other matrix. | | // Iterate over nonzero values of other matrix. | |
|
| for (const_iterator it = x.begin(); it.pos() < x.n_nonzero; it++) | | for (const_iterator it = x.begin(); it != x.end(); it++) | |
| { | | { | |
| get_value(it.row(), it.col()) += *it; | | get_value(it.row(), it.col()) += *it; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator-=(const SpMat<eT>& x) | | SpMat<eT>::operator-=(const SpMat<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtract
ion"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtract
ion"); | |
| | | | |
| // Iterate over nonzero values of other matrix. | | // Iterate over nonzero values of other matrix. | |
|
| for (const_iterator it = x.begin(); it.pos() < x.n_nonzero; it++) | | for (const_iterator it = x.begin(); it != x.end(); it++) | |
| { | | { | |
| get_value(it.row(), it.col()) -= *it; | | get_value(it.row(), it.col()) -= *it; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| | | | |
| skipping to change at line 299 | | skipping to change at line 302 | |
| SpMat<eT>::operator%=(const SpMat<eT>& x) | | SpMat<eT>::operator%=(const SpMat<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | |
| | | | |
| // We can do this with two iterators rather simply. | | // We can do this with two iterators rather simply. | |
| iterator it = begin(); | | iterator it = begin(); | |
| const_iterator x_it = x.begin(); | | const_iterator x_it = x.begin(); | |
| | | | |
|
| while (it.pos() < n_nonzero && x_it.pos() < x.n_nonzero) | | while (it != end() && x_it != x.end()) | |
| { | | { | |
| // One of these will be further advanced than the other (or they will b
e at the same place). | | // One of these will be further advanced than the other (or they will b
e at the same place). | |
| if ((it.row() == x_it.row()) && (it.col() == x_it.col())) | | if ((it.row() == x_it.row()) && (it.col() == x_it.col())) | |
| { | | { | |
| // There is an element at this place in both matrices. Multiply. | | // There is an element at this place in both matrices. Multiply. | |
| (*it) *= (*x_it); | | (*it) *= (*x_it); | |
| | | | |
| // Now move on to the next position. | | // Now move on to the next position. | |
| it++; | | it++; | |
| x_it++; | | x_it++; | |
| | | | |
| skipping to change at line 335 | | skipping to change at line 338 | |
| else /* if our iterator is ahead of the other matrix */ | | else /* if our iterator is ahead of the other matrix */ | |
| { | | { | |
| // In this case we don't need to set anything to 0; our element is al
ready 0. | | // In this case we don't need to set anything to 0; our element is al
ready 0. | |
| // We can just increment the iterator of the other matrix. | | // We can just increment the iterator of the other matrix. | |
| x_it++; | | x_it++; | |
| } | | } | |
| | | | |
| } | | } | |
| | | | |
| // If we are not at the end of our matrix, then we must terminate the rem
aining elements. | | // If we are not at the end of our matrix, then we must terminate the rem
aining elements. | |
|
| while (it.pos() < n_nonzero) | | while (it != end()) | |
| { | | { | |
| (*it) = 0; | | (*it) = 0; | |
| | | | |
| // Hack to manually set the position right... | | // Hack to manually set the position right... | |
| it.internal_pos--; | | it.internal_pos--; | |
| it++; // ...and then an increment. | | it++; // ...and then an increment. | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 361 | | skipping to change at line 364 | |
| SpMat<eT>::SpMat | | SpMat<eT>::SpMat | |
| ( | | ( | |
| const SpBase<typename SpMat<eT>::pod_type, T1>& A, | | const SpBase<typename SpMat<eT>::pod_type, T1>& A, | |
| const SpBase<typename SpMat<eT>::pod_type, T2>& B | | const SpBase<typename SpMat<eT>::pod_type, T2>& B | |
| ) | | ) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
|
| , values(NULL) | | , values(NULL) // extra element is set when mem_resize is called | |
| , row_indices(NULL) | | , row_indices(NULL) | |
| , col_ptrs(NULL) | | , col_ptrs(NULL) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| typedef typename T1::elem_type T; | | typedef typename T1::elem_type T; | |
| | | | |
| // Make sure eT is complex and T is not (compile-time check). | | // Make sure eT is complex and T is not (compile-time check). | |
| arma_type_check(( is_complex<eT>::value == false )); | | arma_type_check(( is_complex<eT>::value == false )); | |
| arma_type_check(( is_complex< T>::value == true )); | | arma_type_check(( is_complex< T>::value == true )); | |
| | | | |
| skipping to change at line 395 | | skipping to change at line 398 | |
| | | | |
| // Set size of matrix correctly. | | // Set size of matrix correctly. | |
| init(l_n_rows, l_n_cols); | | init(l_n_rows, l_n_cols); | |
| mem_resize(n_unique(X, Y, op_n_unique_count())); | | mem_resize(n_unique(X, Y, op_n_unique_count())); | |
| | | | |
| // Now on a second iteration, fill it. | | // Now on a second iteration, fill it. | |
| typename SpMat<T>::const_iterator x_it = X.begin(); | | typename SpMat<T>::const_iterator x_it = X.begin(); | |
| typename SpMat<T>::const_iterator y_it = Y.begin(); | | typename SpMat<T>::const_iterator y_it = Y.begin(); | |
| uword cur_pos = 0; | | uword cur_pos = 0; | |
| | | | |
|
| while ((x_it.pos() < X.n_nonzero) || (y_it.pos() < Y.n_nonzero)) | | while ((x_it != X.end()) || (y_it != Y.end())) | |
| { | | { | |
| if(x_it == y_it) // if we are at the same place | | if(x_it == y_it) // if we are at the same place | |
| { | | { | |
| access::rw(values[cur_pos]) = std::complex<T>((T) *x_it, (T) *y_it); | | access::rw(values[cur_pos]) = std::complex<T>((T) *x_it, (T) *y_it); | |
| access::rw(row_indices[cur_pos]) = x_it.row(); | | access::rw(row_indices[cur_pos]) = x_it.row(); | |
| ++access::rw(col_ptrs[x_it.col() + 1]); | | ++access::rw(col_ptrs[x_it.col() + 1]); | |
| | | | |
| ++x_it; | | ++x_it; | |
| ++y_it; | | ++y_it; | |
| } | | } | |
| | | | |
| skipping to change at line 468 | | skipping to change at line 471 | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const Base<eT, T1>& x) | | SpMat<eT>::SpMat(const Base<eT, T1>& x) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
|
| , values(NULL) | | , values(NULL) // extra element is set when mem_resize is called in opera
tor=() | |
| , row_indices(NULL) | | , row_indices(NULL) | |
| , col_ptrs(NULL) | | , col_ptrs(NULL) | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| (*this).operator=(x); | | (*this).operator=(x); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator=(const Base<eT, T1>& x) | | SpMat<eT>::operator=(const Base<eT, T1>& x) | |
| { | | { | |
|
| //No easy init function, will have to generate matrix manually. | | | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| const Proxy<T1> p(x.get_ref()); | | const Proxy<T1> p(x.get_ref()); | |
| | | | |
| const uword x_n_rows = p.get_n_rows(); | | const uword x_n_rows = p.get_n_rows(); | |
| const uword x_n_cols = p.get_n_cols(); | | const uword x_n_cols = p.get_n_cols(); | |
|
| | | const uword x_n_elem = p.get_n_elem(); | |
| | | | |
| init(x_n_rows, x_n_cols); | | init(x_n_rows, x_n_cols); | |
| | | | |
|
| | | // Count number of nonzero elements in base object. | |
| | | uword n = 0; | |
| | | if(Proxy<T1>::prefer_at_accessor == true) | |
| | | { | |
| | | for(uword j = 0; j < x_n_cols; ++j) | |
| | | { | |
| | | for(uword i = 0; i < x_n_rows; ++i) | |
| | | { | |
| | | if(p.at(i, j) != eT(0)) | |
| | | ++n; | |
| | | } | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | for(uword i = 0; i < x_n_elem; ++i) | |
| | | { | |
| | | if(p[i] != eT(0)) | |
| | | { | |
| | | ++n; | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | mem_resize(n); | |
| | | | |
| | | // Now the memory is resized correctly; add nonzero elements. | |
| | | n = 0; | |
| for(uword j = 0; j < x_n_cols; ++j) | | for(uword j = 0; j < x_n_cols; ++j) | |
|
| for(uword i = 0; i < x_n_rows; ++i) | | | |
| { | | { | |
|
| at(i,j) = p.at(i,j); // let SpValProxy handle 0's. | | for(uword i = 0; i < x_n_rows; ++i) | |
| | | { | |
| | | if(p.at(i, j) != eT(0)) | |
| | | { | |
| | | access::rw(values[n]) = p.at(i, j); | |
| | | access::rw(row_indices[n]) = i; | |
| | | access::rw(col_ptrs[j + 1])++; | |
| | | ++n; | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | // Sum column counts to be column pointers. | |
| | | for(uword c = 1; c <= n_cols; ++c) | |
| | | { | |
| | | access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator*=(const Base<eT, T1>& y) | | SpMat<eT>::operator*=(const Base<eT, T1>& y) | |
| | | | |
| skipping to change at line 555 | | skipping to change at line 600 | |
| // Now we have to fill all the elements using a modification of the NUMBM
M algorithm. | | // Now we have to fill all the elements using a modification of the NUMBM
M algorithm. | |
| uword cur_pos = 0; | | uword cur_pos = 0; | |
| | | | |
| podarray<eT> partial_sums(n_rows); | | podarray<eT> partial_sums(n_rows); | |
| partial_sums.zeros(); | | partial_sums.zeros(); | |
| | | | |
| for(uword col = 0; col < n_cols; ++col) | | for(uword col = 0; col < n_cols; ++col) | |
| { | | { | |
| const_iterator it = begin(); | | const_iterator it = begin(); | |
| | | | |
|
| while(it.pos() < n_nonzero) | | while(it != end()) | |
| { | | { | |
| const eT value = (*it); | | const eT value = (*it); | |
| | | | |
| partial_sums[it.row()] += (value * p.at(it.col(), col)); | | partial_sums[it.row()] += (value * p.at(it.col(), col)); | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| // Now add all partial sums to the matrix. | | // Now add all partial sums to the matrix. | |
| for(uword i = 0; i < n_rows; ++i) | | for(uword i = 0; i < n_rows; ++i) | |
| { | | { | |
|
| if(partial_sums[i] != 0) | | if(partial_sums[i] != eT(0)) | |
| { | | { | |
| access::rw(z.values[cur_pos]) = partial_sums[i]; | | access::rw(z.values[cur_pos]) = partial_sums[i]; | |
| access::rw(z.row_indices[cur_pos]) = i; | | access::rw(z.row_indices[cur_pos]) = i; | |
| ++access::rw(z.col_ptrs[col + 1]); | | ++access::rw(z.col_ptrs[col + 1]); | |
| //printf("colptr %d now %d\n", col + 1, z.col_ptrs[col + 1]); | | //printf("colptr %d now %d\n", col + 1, z.col_ptrs[col + 1]); | |
| ++cur_pos; | | ++cur_pos; | |
| partial_sums[i] = 0; // Would it be faster to do this in batch late
r? | | partial_sums[i] = 0; // Would it be faster to do this in batch late
r? | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| skipping to change at line 636 | | skipping to change at line 681 | |
| | | | |
| const Proxy<T1> p(x.get_ref()); | | const Proxy<T1> p(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise multiplication"); | | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise multiplication"); | |
| | | | |
| // Count the number of elements we will need. | | // Count the number of elements we will need. | |
| SpMat<eT> tmp(n_rows, n_cols); | | SpMat<eT> tmp(n_rows, n_cols); | |
| const_iterator it = begin(); | | const_iterator it = begin(); | |
| uword new_n_nonzero = 0; | | uword new_n_nonzero = 0; | |
| | | | |
|
| while(it.pos() < n_nonzero()) | | while(it != end()) | |
| { | | { | |
| // prefer_at_accessor == false can't save us any work here | | // prefer_at_accessor == false can't save us any work here | |
|
| if(((*it) * x.at(it.row(), it.col())) != 0) | | if(((*it) * p.at(it.row(), it.col())) != eT(0)) | |
| { | | { | |
| ++new_n_nonzero; | | ++new_n_nonzero; | |
| } | | } | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| // Resize. | | // Resize. | |
| tmp.mem_resize(new_n_nonzero); | | tmp.mem_resize(new_n_nonzero); | |
| | | | |
| const_iterator c_it = begin(); | | const_iterator c_it = begin(); | |
| uword cur_pos = 0; | | uword cur_pos = 0; | |
|
| while(c_it.pos() < n_nonzero) | | while(c_it != end()) | |
| { | | { | |
| // prefer_at_accessor == false can't save us any work here | | // prefer_at_accessor == false can't save us any work here | |
|
| const eT val = (*c_it) * x(c_it.row(), c_it.col()); | | const eT val = (*c_it) * p.at(c_it.row(), c_it.col()); | |
| if(val != 0) | | if(val != eT(0)) | |
| { | | { | |
| access::rw(tmp.values[cur_pos]) = val; | | access::rw(tmp.values[cur_pos]) = val; | |
| access::rw(tmp.row_indices[cur_pos]) = c_it.row(); | | access::rw(tmp.row_indices[cur_pos]) = c_it.row(); | |
| ++access::rw(tmp.col_ptrs[c_it.col() + 1]); | | ++access::rw(tmp.col_ptrs[c_it.col() + 1]); | |
| ++cur_pos; | | ++cur_pos; | |
| } | | } | |
| | | | |
| ++c_it; | | ++c_it; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 688 | | skipping to change at line 733 | |
| * Functions on subviews. | | * Functions on subviews. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const SpSubview<eT>& X) | | SpMat<eT>::SpMat(const SpSubview<eT>& X) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
|
| , values(NULL) | | , values(NULL) // extra element added when mem_resize is called | |
| , row_indices(NULL) | | , row_indices(NULL) | |
| , col_ptrs(NULL) | | , col_ptrs(NULL) | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| (*this).operator=(X); | | (*this).operator=(X); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| | | | |
| skipping to change at line 713 | | skipping to change at line 758 | |
| | | | |
| const uword in_n_cols = X.n_cols; | | const uword in_n_cols = X.n_cols; | |
| const uword in_n_rows = X.n_rows; | | const uword in_n_rows = X.n_rows; | |
| | | | |
| const bool alias = (this == &(X.m)); | | const bool alias = (this == &(X.m)); | |
| | | | |
| if(alias == false) | | if(alias == false) | |
| { | | { | |
| init(in_n_rows, in_n_cols); | | init(in_n_rows, in_n_cols); | |
| | | | |
|
| | | const uword x_n_nonzero = X.n_nonzero; | |
| | | | |
| | | mem_resize(x_n_nonzero); | |
| | | | |
| typename SpSubview<eT>::const_iterator it = X.begin(); | | typename SpSubview<eT>::const_iterator it = X.begin(); | |
| | | | |
|
| while(it.pos() < X.n_nonzero) | | while(it != X.end()) | |
| { | | { | |
|
| at(it.row(), it.col()) = (*it); | | access::rw(row_indices[it.pos()]) = it.row(); | |
| | | access::rw(values[it.pos()]) = (*it); | |
| | | ++access::rw(col_ptrs[it.col() + 1]); | |
| ++it; | | ++it; | |
| } | | } | |
|
| | | | |
| | | // Now sum column pointers. | |
| | | for(uword c = 1; c <= n_cols; ++c) | |
| | | { | |
| | | access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | |
| | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // Create it in a temporary. | | // Create it in a temporary. | |
| SpMat<eT> tmp(X); | | SpMat<eT> tmp(X); | |
| | | | |
| steal_mem(tmp); | | steal_mem(tmp); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| | | | |
| skipping to change at line 741 | | skipping to change at line 798 | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator+=(const SpSubview<eT>& X) | | SpMat<eT>::operator+=(const SpSubview<eT>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition
"); | | arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition
"); | |
| | | | |
|
| const uword in_n_cols = X.n_cols; | | typename SpSubview<eT>::const_iterator it = X.begin(); | |
| const uword in_n_rows = X.n_rows; | | | |
| | | | |
| const_iterator it = const_iterator(X.m, X.aux_row1, X.aux_col1); | | | |
| | | | |
|
| while(it.col < (X.aux_col1 + in_n_cols)) | | while(it != X.end()) | |
| { | | { | |
|
| // Is it within the proper range? | | at(it.row(), it.col()) += (*it); | |
| if((it.row >= X.aux_row1) && (it.row < (X.aux_row1 + in_n_rows))) | | | |
| { | | | |
| at(it.row - X.aux_row1, it.col - X.aux_col1) += (*it); | | | |
| } | | | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator-=(const SpSubview<eT>& X) | | SpMat<eT>::operator-=(const SpSubview<eT>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtract
ion"); | | arma_debug_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtract
ion"); | |
| | | | |
|
| const uword in_n_cols = X.n_cols; | | typename SpSubview<eT>::const_iterator it = X.begin(); | |
| const uword in_n_rows = X.n_rows; | | | |
| | | | |
| const_iterator it = const_iterator(X.m, X.aux_row1, X.aux_col1); | | | |
| | | | |
|
| while(it.col < (X.aux_col1 + in_n_cols)) | | while(it != X.end()) | |
| { | | { | |
|
| // Is it within the proper range? | | at(it.row(), it.col()) -= (*it); | |
| if((it.row >= X.aux_row1) && (it.row < (X.aux_row1 + in_n_rows))) | | | |
| { | | | |
| at(it.row - X.aux_row1, it.col - X.aux_col1) -= (*it); | | | |
| } | | | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator*=(const SpSubview<eT>& y) | | SpMat<eT>::operator*=(const SpSubview<eT>& y) | |
| | | | |
| skipping to change at line 813 | | skipping to change at line 854 | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator%=(const SpSubview<eT>& x) | | SpMat<eT>::operator%=(const SpSubview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | |
| | | | |
|
| // We want to iterate over whichever has fewer nonzero points. | | iterator it = begin(); | |
| if (n_nonzero <= x.n_nonzero) | | typename SpSubview<eT>::const_iterator xit = x.begin(); | |
| | | | |
| | | while((it != end()) || (xit != x.end())) | |
| { | | { | |
|
| // Use our iterator. | | if((xit.row() == it.row()) && (xit.col() == it.col())) | |
| for (iterator it = begin(); it.pos() < n_nonzero; it++) | | | |
| { | | { | |
|
| (*it) *= x(it.row(), it.col()); | | (*it) *= (*xit); | |
| | | ++it; | |
| | | ++xit; | |
| } | | } | |
|
| } | | else | |
| else | | | |
| { | | | |
| // Use their iterator. A little more complex... | | | |
| const_iterator it = const_iterator(x.m, x.aux_row1, x.aux_col1); | | | |
| while((it.col() < (x.aux_col1 + x.n_cols))) | | | |
| { | | { | |
|
| if((it.row() >= x.aux_row1) && (it.row() < (x.aux_row1 + x.n_rows))) | | if((xit.col() > it.col()) || ((xit.col() == it.col()) && (xit.row() >
it.row()))) | |
| { | | { | |
|
| at(it.row() - x.aux_row1, it.col() - x.aux_col1) *= (*it); | | // xit is "ahead" | |
| | | (*it) = eT(0); // erase element; x has a zero here | |
| | | it.internal_pos--; // update iterator so it still works | |
| | | ++it; | |
| | | } | |
| | | else | |
| | | { | |
| | | // it is "ahead" | |
| | | ++xit; | |
| } | | } | |
|
| | | | |
| ++it; | | | |
| } | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator/=(const SpSubview<eT>& x) | | SpMat<eT>::operator/=(const SpSubview<eT>& x) | |
| | | | |
| skipping to change at line 869 | | skipping to change at line 914 | |
| * Operators on regular subviews. | | * Operators on regular subviews. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const subview<eT>& x) | | SpMat<eT>::SpMat(const subview<eT>& x) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
|
| , values(NULL) | | , values(NULL) // extra value set in operator=() | |
| , row_indices(NULL) | | , row_indices(NULL) | |
| , col_ptrs(NULL) | | , col_ptrs(NULL) | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| (*this).operator=(x); | | (*this).operator=(x); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator=(const subview<eT>& x) | | SpMat<eT>::operator=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| | | const uword x_n_rows = x.n_rows; | |
| | | const uword x_n_cols = x.n_cols; | |
| | | | |
| // Set the size correctly. | | // Set the size correctly. | |
|
| init(x.n_rows, x.n_cols); | | init(x_n_rows, x_n_cols); | |
| | | | |
| | | // Count number of nonzero elements. | |
| | | uword n = 0; | |
| | | for(uword c = 0; c < x_n_cols; ++c) | |
| | | { | |
| | | for(uword r = 0; r < x_n_rows; ++r) | |
| | | { | |
| | | if(x.at(r, c) != eT(0)) | |
| | | { | |
| | | ++n; | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | // Resize memory appropriately. | |
| | | mem_resize(n); | |
| | | | |
|
| for(uword col = 0; col < x.n_cols; col++) | | n = 0; | |
| | | for(uword c = 0; c < x_n_cols; ++c) | |
| { | | { | |
|
| for(uword row = 0; row < x.n_rows; row++) | | for(uword r = 0; r < x_n_rows; ++r) | |
| { | | { | |
|
| // Add any nonzero values. | | const eT val = x.at(r, c); | |
| at(row, col) = x.at(row, col); | | | |
| | | if(val != eT(0)) | |
| | | { | |
| | | access::rw(values[n]) = val; | |
| | | access::rw(row_indices[n]) = r; | |
| | | ++access::rw(col_ptrs[c + 1]); | |
| | | ++n; | |
| | | } | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | // Fix column counts into column pointers. | |
| | | for(uword c = 1; c <= n_cols; ++c) | |
| | | { | |
| | | access::rw(col_ptrs[c]) += col_ptrs[c - 1]; | |
| | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator+=(const subview<eT>& x) | | SpMat<eT>::operator+=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition
"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "addition
"); | |
| | | | |
| // Loop over every element. This could probably be written in a more | | // Loop over every element. This could probably be written in a more | |
| // efficient way, by calculating the number of nonzero elements the outpu
t | | // efficient way, by calculating the number of nonzero elements the outpu
t | |
| // matrix will have, allocating the memory correctly, and then filling th
e | | // matrix will have, allocating the memory correctly, and then filling th
e | |
| // matrix correctly. However... for now, this works okay. | | // matrix correctly. However... for now, this works okay. | |
| for(uword col = 0; col < n_cols; ++col) | | for(uword col = 0; col < n_cols; ++col) | |
| { | | { | |
| for(uword row = 0; row < n_rows; ++row) | | for(uword row = 0; row < n_rows; ++row) | |
| { | | { | |
|
| at(row, col) += x(row, col); | | at(row, col) += x.at(row, col); | |
| } | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator-=(const subview<eT>& x) | | SpMat<eT>::operator-=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtract
ion"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "subtract
ion"); | |
| | | | |
| // Loop over every element. | | // Loop over every element. | |
| for(uword col = 0; col < n_cols; ++col) | | for(uword col = 0; col < n_cols; ++col) | |
| { | | { | |
| for(uword row = 0; row < n_rows; ++row) | | for(uword row = 0; row < n_rows; ++row) | |
| { | | { | |
|
| at(row, col) -= x(row, col); | | at(row, col) -= x.at(row, col); | |
| } | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator*=(const subview<eT>& y) | | SpMat<eT>::operator*=(const subview<eT>& y) | |
| | | | |
| skipping to change at line 987 | | skipping to change at line 1065 | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise multiplication"); | |
| | | | |
| // Loop over every element. | | // Loop over every element. | |
| for(uword col = 0; col < n_cols; ++col) | | for(uword col = 0; col < n_cols; ++col) | |
| { | | { | |
| for(uword row = 0; row < n_rows; ++row) | | for(uword row = 0; row < n_rows; ++row) | |
| { | | { | |
|
| at(row, col) *= x(row, col); | | at(row, col) *= x.at(row, col); | |
| } | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::operator/=(const subview<eT>& x) | | SpMat<eT>::operator/=(const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise division"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-
wise division"); | |
| | | | |
| // Loop over every element. | | // Loop over every element. | |
| for(uword col = 0; col < n_cols; ++col) | | for(uword col = 0; col < n_cols; ++col) | |
| { | | { | |
| for(uword row = 0; row < n_rows; ++row) | | for(uword row = 0; row < n_rows; ++row) | |
| { | | { | |
|
| at(row, col) /= x(row, col); | | at(row, col) /= x.at(row, col); | |
| } | | } | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1, typename spop_type> | | template<typename T1, typename spop_type> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const SpOp<T1, spop_type>& X) | | SpMat<eT>::SpMat(const SpOp<T1, spop_type>& X) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
|
| , values(NULL) | | , values(NULL) // set in application of sparse operation | |
| , row_indices(NULL) | | , row_indices(NULL) | |
| , col_ptrs(NULL) | | , col_ptrs(NULL) | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == fa
lse )); | | arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == fa
lse )); | |
| | | | |
| spop_type::apply(*this, X); | | spop_type::apply(*this, X); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1134 | | skipping to change at line 1212 | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1, typename T2, typename spglue_type> | | template<typename T1, typename T2, typename spglue_type> | |
| inline | | inline | |
| SpMat<eT>::SpMat(const SpGlue<T1, T2, spglue_type>& X) | | SpMat<eT>::SpMat(const SpGlue<T1, T2, spglue_type>& X) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
|
| , values(NULL) | | , values(NULL) // extra element set in application of sparse glue | |
| , row_indices(NULL) | | , row_indices(NULL) | |
| , col_ptrs(NULL) | | , col_ptrs(NULL) | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == fa
lse )); | | arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == fa
lse )); | |
| | | | |
| spglue_type::apply(*this, X); | | spglue_type::apply(*this, X); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 1262 | | skipping to change at line 1340 | |
| return SpSubview<eT>(*this, row_num, 0, 1, n_cols); | | return SpSubview<eT>(*this, row_num, 0, 1, n_cols); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpSubview<eT> | | SpSubview<eT> | |
| SpMat<eT>::operator()(const uword row_num, const span& col_span) | | SpMat<eT>::operator()(const uword row_num, const span& col_span) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| return SpSubview<eT>(*this, row_num, col_span.a, col_span.b - col_span.a | | const bool col_all = col_span.whole; | |
| + 1); | | | |
| | | const uword local_n_cols = n_cols; | |
| | | | |
| | | const uword in_col1 = col_all ? 0 : col_span.a; | |
| | | const uword in_col2 = col_span.b; | |
| | | const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + | |
| | | 1; | |
| | | | |
| | | arma_debug_check | |
| | | ( | |
| | | (row_num >= n_rows) | |
| | | || | |
| | | ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) | |
| | | ) | |
| | | , | |
| | | "SpMat::operator(): indices out of bounds or incorrectly used" | |
| | | ); | |
| | | | |
| | | return SpSubview<eT>(*this, row_num, in_col1, 1, submat_n_cols); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT> | | const SpSubview<eT> | |
| SpMat<eT>::operator()(const uword row_num, const span& col_span) const | | SpMat<eT>::operator()(const uword row_num, const span& col_span) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| return SpSubview<eT>(*this, row_num, col_span.a, col_span.b - col_span.a | | const bool col_all = col_span.whole; | |
| + 1); | | | |
| | | const uword local_n_cols = n_cols; | |
| | | | |
| | | const uword in_col1 = col_all ? 0 : col_span.a; | |
| | | const uword in_col2 = col_span.b; | |
| | | const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + | |
| | | 1; | |
| | | | |
| | | arma_debug_check | |
| | | ( | |
| | | (row_num >= n_rows) | |
| | | || | |
| | | ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) | |
| | | ) | |
| | | , | |
| | | "SpMat::operator(): indices out of bounds or incorrectly used" | |
| | | ); | |
| | | | |
| | | return SpSubview<eT>(*this, row_num, in_col1, 1, submat_n_cols); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_inline | | arma_inline | |
| SpSubview<eT> | | SpSubview<eT> | |
| SpMat<eT>::col(const uword col_num) | | SpMat<eT>::col(const uword col_num) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| return SpSubview<eT>(*this, 0, col_num, n_rows, 1); | | return SpSubview<eT>(*this, 0, col_num, n_rows, 1); | |
| | | | |
| skipping to change at line 1302 | | skipping to change at line 1414 | |
| return SpSubview<eT>(*this, 0, col_num, n_rows, 1); | | return SpSubview<eT>(*this, 0, col_num, n_rows, 1); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpSubview<eT> | | SpSubview<eT> | |
| SpMat<eT>::operator()(const span& row_span, const uword col_num) | | SpMat<eT>::operator()(const span& row_span, const uword col_num) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| return SpSubview<eT>(*this, row_span.a, col_num, row_span.b - row_span.a | | const bool row_all = row_span.whole; | |
| + 1, 0); | | | |
| | | const uword local_n_rows = n_rows; | |
| | | | |
| | | const uword in_row1 = row_all ? 0 : row_span.a; | |
| | | const uword in_row2 = row_span.b; | |
| | | const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + | |
| | | 1; | |
| | | | |
| | | arma_debug_check | |
| | | ( | |
| | | (col_num >= n_cols) | |
| | | || | |
| | | ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) | |
| | | ) | |
| | | , | |
| | | "SpMat::operator(): indices out of bounds or incorrectly used" | |
| | | ); | |
| | | | |
| | | return SpSubview<eT>(*this, in_row1, col_num, submat_n_rows, 1); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT> | | const SpSubview<eT> | |
| SpMat<eT>::operator()(const span& row_span, const uword col_num) const | | SpMat<eT>::operator()(const span& row_span, const uword col_num) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| return SpSubview<eT>(*this, row_span.a, col_num, row_span.b - row_span.a | | const bool row_all = row_span.whole; | |
| + 1, 0); | | | |
| | | const uword local_n_rows = n_rows; | |
| | | | |
| | | const uword in_row1 = row_all ? 0 : row_span.a; | |
| | | const uword in_row2 = row_span.b; | |
| | | const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + | |
| | | 1; | |
| | | | |
| | | arma_debug_check | |
| | | ( | |
| | | (col_num >= n_cols) | |
| | | || | |
| | | ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) | |
| | | ) | |
| | | , | |
| | | "SpMat::operator(): indices out of bounds or incorrectly used" | |
| | | ); | |
| | | | |
| | | return SpSubview<eT>(*this, in_row1, col_num, submat_n_rows, 1); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Swap in_row1 with in_row2. | | * Swap in_row1 with in_row2. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::swap_rows(const uword in_row1, const uword in_row2) | | SpMat<eT>::swap_rows(const uword in_row1, const uword in_row2) | |
| { | | { | |
| | | | |
| skipping to change at line 1608 | | skipping to change at line 1754 | |
| // Copy first set of columns (no manipulation required). | | // Copy first set of columns (no manipulation required). | |
| if (in_col1 != 0) | | if (in_col1 != 0) | |
| { | | { | |
| arrayops::copy(new_col_ptrs, col_ptrs, in_col1); | | arrayops::copy(new_col_ptrs, col_ptrs, in_col1); | |
| } | | } | |
| | | | |
| // Copy second set of columns (manipulation required). | | // Copy second set of columns (manipulation required). | |
| uword cur_col = in_col1; | | uword cur_col = in_col1; | |
| for (uword i = in_col2 + 1; i <= n_cols; ++i, ++cur_col) | | for (uword i = in_col2 + 1; i <= n_cols; ++i, ++cur_col) | |
| { | | { | |
|
| std::cout << "i " << i << " n_cols " << n_cols << std::endl; | | | |
| new_col_ptrs[cur_col] = col_ptrs[i] - diff; | | new_col_ptrs[cur_col] = col_ptrs[i] - diff; | |
| } | | } | |
| | | | |
| memory::release(col_ptrs); | | memory::release(col_ptrs); | |
| access::rw(col_ptrs) = new_col_ptrs; | | access::rw(col_ptrs) = new_col_ptrs; | |
| | | | |
| // We update the element and column counts, and we're done. | | // We update the element and column counts, and we're done. | |
| access::rw(n_cols) = new_n_cols; | | access::rw(n_cols) = new_n_cols; | |
| access::rw(n_elem) = n_cols * n_rows; | | access::rw(n_elem) = n_cols * n_rows; | |
| } | | } | |
| | | | |
| skipping to change at line 2297 | | skipping to change at line 2442 | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if (dim == 0) | | if (dim == 0) | |
| { | | { | |
| // We have to modify all of the relevant row indices and the relevant c
olumn pointers. | | // We have to modify all of the relevant row indices and the relevant c
olumn pointers. | |
| // Iterate over all the points to do this. We won't be deleting any po
ints, but we will be modifying | | // Iterate over all the points to do this. We won't be deleting any po
ints, but we will be modifying | |
| // columns and rows. We'll have to store a new set of column vectors. | | // columns and rows. We'll have to store a new set of column vectors. | |
| uword* new_col_ptrs = memory::acquire<uword>(in_cols + 1); | | uword* new_col_ptrs = memory::acquire<uword>(in_cols + 1); | |
| | | | |
|
| uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero); | | uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero + 1); | |
| | | access::rw(new_row_indices[n_nonzero]) = 0; | |
| | | | |
| arrayops::inplace_set(new_col_ptrs, uword(0), in_cols + 1); | | arrayops::inplace_set(new_col_ptrs, uword(0), in_cols + 1); | |
| | | | |
|
| for(const_iterator it = begin(); it.pos() < n_nonzero; it++) | | for(const_iterator it = begin(); it != end(); it++) | |
| { | | { | |
| uword vector_position = (it.col() * n_rows) + it.row(); | | uword vector_position = (it.col() * n_rows) + it.row(); | |
| new_row_indices[it.pos()] = vector_position % in_rows; | | new_row_indices[it.pos()] = vector_position % in_rows; | |
| ++new_col_ptrs[vector_position / in_rows + 1]; | | ++new_col_ptrs[vector_position / in_rows + 1]; | |
| } | | } | |
| | | | |
| // Now sum the column counts to get the new column pointers. | | // Now sum the column counts to get the new column pointers. | |
| for(uword i = 1; i <= in_cols; i++) | | for(uword i = 1; i <= in_cols; i++) | |
| { | | { | |
| access::rw(new_col_ptrs[i]) += new_col_ptrs[i - 1]; | | access::rw(new_col_ptrs[i]) += new_col_ptrs[i - 1]; | |
| | | | |
| skipping to change at line 2353 | | skipping to change at line 2499 | |
| const SpMat<eT>& | | const SpMat<eT>& | |
| SpMat<eT>::zeros() | | SpMat<eT>::zeros() | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if (n_nonzero > 0) | | if (n_nonzero > 0) | |
| { | | { | |
| memory::release(values); | | memory::release(values); | |
| memory::release(row_indices); | | memory::release(row_indices); | |
| | | | |
|
| access::rw(values) = NULL; | | access::rw(values) = memory::acquire_chunked<eT>(1); | |
| access::rw(row_indices) = NULL; | | access::rw(row_indices) = memory::acquire_chunked<uword>(1); | |
| | | | |
| | | access::rw(values[0]) = 0; | |
| | | access::rw(row_indices[0]) = 0; | |
| } | | } | |
| | | | |
| access::rw(n_nonzero) = 0; | | access::rw(n_nonzero) = 0; | |
| arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1); | | arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1); | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| | | | |
| skipping to change at line 2887 | | skipping to change at line 3036 | |
| : false | | : false | |
| ), | | ), | |
| "SpMat::init(): requested size is too large" | | "SpMat::init(): requested size is too large" | |
| ); | | ); | |
| | | | |
| // Clean out the existing memory. | | // Clean out the existing memory. | |
| if (values) | | if (values) | |
| { | | { | |
| memory::release(values); | | memory::release(values); | |
| memory::release(row_indices); | | memory::release(row_indices); | |
|
| | | | |
| access::rw(values) = NULL; | | | |
| access::rw(row_indices) = NULL; | | | |
| } | | } | |
| | | | |
|
| | | access::rw(values) = memory::acquire_chunked<eT>(1); | |
| | | access::rw(row_indices) = memory::acquire_chunked<uword>(1); | |
| | | | |
| | | access::rw(values[0]) = 0; | |
| | | access::rw(row_indices[0]) = 0; | |
| | | | |
| memory::release(col_ptrs); | | memory::release(col_ptrs); | |
| | | | |
| // Set the new size accordingly. | | // Set the new size accordingly. | |
| access::rw(n_rows) = in_rows; | | access::rw(n_rows) = in_rows; | |
| access::rw(n_cols) = in_cols; | | access::rw(n_cols) = in_cols; | |
| access::rw(n_elem) = (in_rows * in_cols); | | access::rw(n_elem) = (in_rows * in_cols); | |
| access::rw(n_nonzero) = 0; | | access::rw(n_nonzero) = 0; | |
| | | | |
| // Try to allocate the column pointers, filling them with 0. | | // Try to allocate the column pointers, filling them with 0. | |
| access::rw(col_ptrs) = memory::acquire<uword>(in_cols + 1); | | access::rw(col_ptrs) = memory::acquire<uword>(in_cols + 1); | |
| | | | |
| skipping to change at line 2988 | | skipping to change at line 3140 | |
| | | | |
| std::string::size_type line_len = line_end - line_start + 1; | | std::string::size_type line_len = line_end - line_start + 1; | |
| std::stringstream line_stream(text.substr(line_start, line_len)); | | std::stringstream line_stream(text.substr(line_start, line_len)); | |
| | | | |
| uword col = 0; | | uword col = 0; | |
| eT val; | | eT val; | |
| | | | |
| while (line_stream >> val) | | while (line_stream >> val) | |
| { | | { | |
| // Only add nonzero elements. | | // Only add nonzero elements. | |
|
| if (val != 0) | | if (val != eT(0)) | |
| { | | { | |
| get_value(row, col) = val; | | get_value(row, col) = val; | |
| } | | } | |
| | | | |
| ++col; | | ++col; | |
| } | | } | |
| | | | |
| ++row; | | ++row; | |
| line_start = line_end + 1; | | line_start = line_end + 1; | |
| | | | |
| | | | |
| skipping to change at line 3018 | | skipping to change at line 3170 | |
| void | | void | |
| SpMat<eT>::init(const SpMat<eT>& x) | | SpMat<eT>::init(const SpMat<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // Ensure we are not initializing to ourselves. | | // Ensure we are not initializing to ourselves. | |
| if (this != &x) | | if (this != &x) | |
| { | | { | |
| init(x.n_rows, x.n_cols); | | init(x.n_rows, x.n_cols); | |
| | | | |
|
| // values and row_indices are null. | | // values and row_indices may not be null. | |
| access::rw(values) = memory::acquire_chunked<eT> (x.n_nonzero); | | if (values != NULL) | |
| access::rw(row_indices) = memory::acquire_chunked<uword>(x.n_nonzero); | | { | |
| | | memory::release(values); | |
| | | memory::release(row_indices); | |
| | | } | |
| | | | |
| | | access::rw(values) = memory::acquire_chunked<eT> (x.n_nonzero + | |
| | | 1); | |
| | | access::rw(row_indices) = memory::acquire_chunked<uword>(x.n_nonzero + | |
| | | 1); | |
| | | | |
| // Now copy over the elements. | | // Now copy over the elements. | |
|
| arrayops::copy(access::rwp(values), x.values, x.n_nonzero); | | arrayops::copy(access::rwp(values), x.values, x.n_nonzero + 1 | |
| arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero); | | ); | |
| | | arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero + 1 | |
| | | ); | |
| arrayops::copy(access::rwp(col_ptrs), x.col_ptrs, x.n_cols + 1); | | arrayops::copy(access::rwp(col_ptrs), x.col_ptrs, x.n_cols + 1); | |
| | | | |
| access::rw(n_nonzero) = x.n_nonzero; | | access::rw(n_nonzero) = x.n_nonzero; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::mem_resize(const uword new_n_nonzero) | | SpMat<eT>::mem_resize(const uword new_n_nonzero) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(n_nonzero != new_n_nonzero) | | if(n_nonzero != new_n_nonzero) | |
| { | | { | |
| if(new_n_nonzero == 0) | | if(new_n_nonzero == 0) | |
| { | | { | |
| memory::release(values); | | memory::release(values); | |
| memory::release(row_indices); | | memory::release(row_indices); | |
| | | | |
|
| access::rw(values) = NULL; | | access::rw(values) = memory::acquire_chunked<eT> (1); | |
| access::rw(row_indices) = NULL; | | access::rw(row_indices) = memory::acquire_chunked<uword>(1); | |
| | | | |
| | | access::rw(values[0]) = 0; | |
| | | access::rw(row_indices[0]) = 0; | |
| } | | } | |
| else | | else | |
| { | | { | |
| // Figure out the actual amount of memory currently allocated | | // Figure out the actual amount of memory currently allocated | |
| // NOTE: this relies on memory::acquire_chunked() being used for the
'values' and 'row_indices' arrays | | // NOTE: this relies on memory::acquire_chunked() being used for the
'values' and 'row_indices' arrays | |
| const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero)
; | | const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero)
; | |
| | | | |
| if(n_alloc < new_n_nonzero) | | if(n_alloc < new_n_nonzero) | |
| { | | { | |
|
| eT* new_values = memory::acquire_chunked<eT> (new_n_nonze | | eT* new_values = memory::acquire_chunked<eT> (new_n_nonze | |
| ro); | | ro + 1); | |
| uword* new_row_indices = memory::acquire_chunked<uword>(new_n_nonze | | uword* new_row_indices = memory::acquire_chunked<uword>(new_n_nonze | |
| ro); | | ro + 1); | |
| | | | |
| | | access::rw(new_values[new_n_nonzero]) = 0; | |
| | | access::rw(new_row_indices[new_n_nonzero]) = 0; | |
| | | | |
| if(n_nonzero > 0) | | if(n_nonzero > 0) | |
| { | | { | |
| // Copy old elements. | | // Copy old elements. | |
| uword copy_size = std::min(n_nonzero, new_n_nonzero); | | uword copy_size = std::min(n_nonzero, new_n_nonzero); | |
| | | | |
| arrayops::copy(new_values, values, copy_size); | | arrayops::copy(new_values, values, copy_size); | |
| arrayops::copy(new_row_indices, row_indices, copy_size); | | arrayops::copy(new_row_indices, row_indices, copy_size); | |
| | | | |
| memory::release(values); | | memory::release(values); | |
| | | | |
| skipping to change at line 3143 | | skipping to change at line 3307 | |
| SpMat<eT>::begin() const | | SpMat<eT>::begin() const | |
| { | | { | |
| return const_iterator(*this); | | return const_iterator(*this); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpMat<eT>::iterator | | typename SpMat<eT>::iterator | |
| SpMat<eT>::end() | | SpMat<eT>::end() | |
| { | | { | |
|
| return iterator(*this, n_nonzero); | | return iterator(*this, 0, n_cols, n_nonzero); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpMat<eT>::const_iterator | | typename SpMat<eT>::const_iterator | |
| SpMat<eT>::end() const | | SpMat<eT>::end() const | |
| { | | { | |
|
| return const_iterator(*this, n_nonzero); | | return const_iterator(*this, 0, n_cols, n_nonzero); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpMat<eT>::iterator | | typename SpMat<eT>::iterator | |
| SpMat<eT>::begin_col(const uword col_num) | | SpMat<eT>::begin_col(const uword col_num) | |
| { | | { | |
| return iterator(*this, 0, col_num); | | return iterator(*this, 0, col_num); | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 3244 | | skipping to change at line 3408 | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::clear() | | SpMat<eT>::clear() | |
| { | | { | |
| if (values) | | if (values) | |
| { | | { | |
| memory::release(values); | | memory::release(values); | |
| memory::release(row_indices); | | memory::release(row_indices); | |
| | | | |
|
| values = NULL; | | access::rw(values) = memory::acquire_chunked<eT> (1); | |
| row_indices = NULL; | | access::rw(row_indices) = memory::acquire_chunked<uword>(1); | |
| | | | |
| | | access::rw(values[0]) = 0; | |
| | | access::rw(row_indices[0]) = 0; | |
| } | | } | |
| | | | |
| memory::release(col_ptrs); | | memory::release(col_ptrs); | |
| | | | |
| access::rw(col_ptrs) = memory::acquire<uword>(n_cols + 1); | | access::rw(col_ptrs) = memory::acquire<uword>(n_cols + 1); | |
| | | | |
| arrayops::inplace_set(col_ptrs, eT(0), n_cols + 1); | | arrayops::inplace_set(col_ptrs, eT(0), n_cols + 1); | |
| | | | |
| access::rw(n_nonzero) = 0; | | access::rw(n_nonzero) = 0; | |
| } | | } | |
| | | | |
| skipping to change at line 3462 | | skipping to change at line 3629 | |
| // | | // | |
| | | | |
| // We have to update the rest of the column pointers. | | // We have to update the rest of the column pointers. | |
| for (uword i = in_col + 1; i < n_cols + 1; i++) | | for (uword i = in_col + 1; i < n_cols + 1; i++) | |
| { | | { | |
| access::rw(col_ptrs[i])++; // We are only inserting one new element. | | access::rw(col_ptrs[i])++; // We are only inserting one new element. | |
| } | | } | |
| | | | |
| // Figure out the actual amount of memory currently allocated | | // Figure out the actual amount of memory currently allocated | |
| // NOTE: this relies on memory::acquire_chunked() being used for the 'val
ues' and 'row_indices' arrays | | // NOTE: this relies on memory::acquire_chunked() being used for the 'val
ues' and 'row_indices' arrays | |
|
| const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero); | | const uword n_alloc = memory::enlarge_to_mult_of_chunksize(n_nonzero + 1)
; | |
| | | | |
| // If possible, avoid time-consuming memory allocation | | // If possible, avoid time-consuming memory allocation | |
|
| if(n_alloc > n_nonzero) | | if(n_alloc > (n_nonzero + 1)) | |
| { | | { | |
|
| if (pos != n_nonzero) | | arrayops::copy_backwards(access::rwp(values) + pos + 1, values | |
| { | | + pos, (n_nonzero - pos) + 1); | |
| arrayops::copy_backwards(access::rwp(values) + pos + 1, values | | arrayops::copy_backwards(access::rwp(row_indices) + pos + 1, row_indice | |
| + pos, (n_nonzero - pos)); | | s + pos, (n_nonzero - pos) + 1); | |
| arrayops::copy_backwards(access::rwp(row_indices) + pos + 1, row_indi | | | |
| ces + pos, (n_nonzero - pos)); | | | |
| } | | | |
| | | | |
| // Insert the new element. | | // Insert the new element. | |
| access::rw(values[pos]) = val; | | access::rw(values[pos]) = val; | |
| access::rw(row_indices[pos]) = in_row; | | access::rw(row_indices[pos]) = in_row; | |
| | | | |
| access::rw(n_nonzero)++; | | access::rw(n_nonzero)++; | |
| } | | } | |
| else | | else | |
| { | | { | |
| const uword old_n_nonzero = n_nonzero; | | const uword old_n_nonzero = n_nonzero; | |
| | | | |
| access::rw(n_nonzero)++; // Add to count of nonzero elements. | | access::rw(n_nonzero)++; // Add to count of nonzero elements. | |
| | | | |
| // Allocate larger memory. | | // Allocate larger memory. | |
|
| eT* new_values = memory::acquire_chunked<eT> (n_nonzero); | | eT* new_values = memory::acquire_chunked<eT> (n_nonzero + 1); | |
| uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero); | | uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero + 1); | |
| | | | |
| // Copy things over, before the new element. | | // Copy things over, before the new element. | |
| if (pos > 0) | | if (pos > 0) | |
| { | | { | |
| arrayops::copy(new_values, values, pos); | | arrayops::copy(new_values, values, pos); | |
| arrayops::copy(new_row_indices, row_indices, pos); | | arrayops::copy(new_row_indices, row_indices, pos); | |
| } | | } | |
| | | | |
| // Insert the new element. | | // Insert the new element. | |
| new_values[pos] = val; | | new_values[pos] = val; | |
| new_row_indices[pos] = in_row; | | new_row_indices[pos] = in_row; | |
| | | | |
|
| // Copy the rest of things over. | | // Copy the rest of things over (including the extra element at the end | |
| if (pos != old_n_nonzero) | | ). | |
| { | | arrayops::copy(new_values + pos + 1, values + pos, (old_n_non | |
| arrayops::copy(new_values + pos + 1, values + pos, (old_n_n | | zero - pos) + 1); | |
| onzero - pos)); | | arrayops::copy(new_row_indices + pos + 1, row_indices + pos, (old_n_non | |
| arrayops::copy(new_row_indices + pos + 1, row_indices + pos, (old_n_n | | zero - pos) + 1); | |
| onzero - pos)); | | | |
| } | | | |
| | | | |
| // Assign new pointers. | | // Assign new pointers. | |
|
| if (old_n_nonzero != 0) | | memory::release(values); | |
| { | | memory::release(row_indices); | |
| memory::release(values); | | | |
| memory::release(row_indices); | | | |
| } | | | |
| | | | |
| access::rw(values) = new_values; | | access::rw(values) = new_values; | |
| access::rw(row_indices) = new_row_indices; | | access::rw(row_indices) = new_row_indices; | |
| } | | } | |
| | | | |
| return access::rw(values[pos]); | | return access::rw(values[pos]); | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Delete an element at the given position. | | * Delete an element at the given position. | |
| | | | |
| skipping to change at line 3553 | | skipping to change at line 3711 | |
| // Let's see if we are one of them. | | // Let's see if we are one of them. | |
| for (uword pos = colptr; pos < next_colptr; pos++) | | for (uword pos = colptr; pos < next_colptr; pos++) | |
| { | | { | |
| if (in_row == row_indices[pos]) | | if (in_row == row_indices[pos]) | |
| { | | { | |
| const uword old_n_nonzero = n_nonzero; | | const uword old_n_nonzero = n_nonzero; | |
| | | | |
| --access::rw(n_nonzero); // Remove one from the count of nonzero el
ements. | | --access::rw(n_nonzero); // Remove one from the count of nonzero el
ements. | |
| | | | |
| // Found it. Now remove it. | | // Found it. Now remove it. | |
|
| if (n_nonzero == 0) | | | |
| { | | | |
| memory::release(values); | | | |
| memory::release(row_indices); | | | |
| | | | |
|
| access::rw(values) = NULL; | | // Figure out the actual amount of memory currently allocated and t | |
| access::rw(row_indices) = NULL; | | he actual amount that will be required | |
| | | // NOTE: this relies on memory::acquire_chunked() being used for th | |
| | | e 'values' and 'row_indices' arrays | |
| | | | |
| | | const uword n_alloc = memory::enlarge_to_mult_of_chunksize(old_ | |
| | | n_nonzero + 1); | |
| | | const uword n_alloc_mod = memory::enlarge_to_mult_of_chunksize(n_no | |
| | | nzero + 1); | |
| | | | |
| | | // If possible, avoid time-consuming memory allocation | |
| | | if(n_alloc_mod == n_alloc) | |
| | | { | |
| | | if (pos < n_nonzero) // remember, we decremented n_nonzero | |
| | | { | |
| | | arrayops::copy_forwards(access::rwp(values) + pos, values | |
| | | + pos + 1, (n_nonzero - pos) + 1); | |
| | | arrayops::copy_forwards(access::rwp(row_indices) + pos, row_ind | |
| | | ices + pos + 1, (n_nonzero - pos) + 1); | |
| | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| // Figure out the actual amount of memory currently allocated and | | // Make new arrays. | |
| the actual amount that will be required | | eT* new_values = memory::acquire_chunked<eT> (n_nonzero | |
| // NOTE: this relies on memory::acquire_chunked() being used for | | + 1); | |
| the 'values' and 'row_indices' arrays | | uword* new_row_indices = memory::acquire_chunked<uword>(n_nonzero | |
| | | + 1); | |
| const uword n_alloc = memory::enlarge_to_mult_of_chunksize(ol | | | |
| d_n_nonzero); | | | |
| const uword n_alloc_mod = memory::enlarge_to_mult_of_chunksize( | | | |
| n_nonzero); | | | |
| | | | |
|
| // If possible, avoid time-consuming memory allocation | | if (pos > 0) | |
| if(n_alloc_mod == n_alloc) | | | |
| { | | { | |
|
| if (pos < n_nonzero) // remember, we decremented n_nonzero | | arrayops::copy(new_values, values, pos); | |
| { | | arrayops::copy(new_row_indices, row_indices, pos); | |
| arrayops::copy_forwards(access::rwp(values) + pos, value | | | |
| s + pos + 1, (n_nonzero - pos)); | | | |
| arrayops::copy_forwards(access::rwp(row_indices) + pos, row_i | | | |
| ndices + pos + 1, (n_nonzero - pos)); | | | |
| } | | | |
| } | | } | |
|
| else | | | |
| { | | | |
| // Make new arrays. | | | |
| eT* new_values = memory::acquire_chunked<eT> (n_nonze | | | |
| ro); | | | |
| uword* new_row_indices = memory::acquire_chunked<uword>(n_nonze | | | |
| ro); | | | |
| | | | |
| if (pos > 0) | | | |
| { | | | |
| arrayops::copy(new_values, values, pos); | | | |
| arrayops::copy(new_row_indices, row_indices, pos); | | | |
| } | | | |
| | | | |
| if (pos < n_nonzero) // remember, we decremented n_nonzero | | | |
| { | | | |
| arrayops::copy(new_values + pos, values + pos + 1, | | | |
| (n_nonzero - pos)); | | | |
| arrayops::copy(new_row_indices + pos, row_indices + pos + 1, | | | |
| (n_nonzero - pos)); | | | |
| } | | | |
| | | | |
|
| memory::release(values); | | arrayops::copy(new_values + pos, values + pos + 1, (n_n | |
| memory::release(row_indices); | | onzero - pos) + 1); | |
| | | arrayops::copy(new_row_indices + pos, row_indices + pos + 1, (n_n | |
| | | onzero - pos) + 1); | |
| | | | |
|
| access::rw(values) = new_values; | | memory::release(values); | |
| access::rw(row_indices) = new_row_indices; | | memory::release(row_indices); | |
| } | | | |
| | | access::rw(values) = new_values; | |
| | | access::rw(row_indices) = new_row_indices; | |
| } | | } | |
| | | | |
| // And lastly, update all the column pointers (decrement by one). | | // And lastly, update all the column pointers (decrement by one). | |
| for (uword i = in_col + 1; i < n_cols + 1; i++) | | for (uword i = in_col + 1; i < n_cols + 1; i++) | |
| { | | { | |
| --access::rw(col_ptrs[i]); // We only removed one element. | | --access::rw(col_ptrs[i]); // We only removed one element. | |
| } | | } | |
| | | | |
| return; // There is nothing left to do. | | return; // There is nothing left to do. | |
| } | | } | |
| | | | |
End of changes. 83 change blocks. |
| 177 lines changed or deleted | | 331 lines changed or added | |
|
| SpSubview_meat.hpp | | SpSubview_meat.hpp | |
| | | | |
| skipping to change at line 89 | | skipping to change at line 89 | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator+=(const eT val) | | SpSubview<eT>::operator+=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| if(val == 0) | | if(val == eT(0)) | |
| { | | { | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| const uword start_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword end_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| const uword start_col = aux_col1; | | const uword start_col = aux_col1; | |
| const uword end_col = aux_col1 + n_cols; | | const uword end_col = aux_col1 + n_cols; | |
| | | | |
| const uword old_n_nonzero = m.n_nonzero; | | const uword old_n_nonzero = m.n_nonzero; | |
| | | | |
| skipping to change at line 124 | | skipping to change at line 124 | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator-=(const eT val) | | SpSubview<eT>::operator-=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| if(val == 0) | | if(val == eT(0)) | |
| { | | { | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| const uword start_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword end_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| const uword start_col = aux_col1; | | const uword start_col = aux_col1; | |
| const uword end_col = aux_col1 + n_cols; | | const uword end_col = aux_col1 + n_cols; | |
| | | | |
| const uword old_n_nonzero = m.n_nonzero; | | const uword old_n_nonzero = m.n_nonzero; | |
| | | | |
| skipping to change at line 161 | | skipping to change at line 161 | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator*=(const eT val) | | SpSubview<eT>::operator*=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(val == eT(0)) | | if(val == eT(0)) | |
| { | | { | |
| // Turn it all into zeros. | | // Turn it all into zeros. | |
|
| for(iterator it(*this); it.pos() < n_nonzero; ++it) | | for(iterator it(*this); it != end(); ++it) | |
| { | | { | |
| (*it) = eT(0); // zero out the value. | | (*it) = eT(0); // zero out the value. | |
| it.internal_pos--; | | it.internal_pos--; | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| const uword start_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword end_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| | | | |
| skipping to change at line 201 | | skipping to change at line 201 | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator/=(const eT val) | | SpSubview<eT>::operator/=(const eT val) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| const uword start_col = aux_col1; | | const uword start_col = aux_col1; | |
| const uword end_col = aux_col1 + n_cols; | | const uword end_col = aux_col1 + n_cols; | |
| const uword start_row = aux_row1; | | const uword start_row = aux_row1; | |
| const uword end_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| | | | |
|
| | | const uword old_n_nonzero = m.n_nonzero; | |
| | | | |
| for(uword c = start_col; c < end_col; ++c) | | for(uword c = start_col; c < end_col; ++c) | |
| { | | { | |
| for(uword r = start_row; r < end_row; ++r) | | for(uword r = start_row; r < end_row; ++r) | |
| { | | { | |
| access::rw(m).at(r, c) /= val; | | access::rw(m).at(r, c) /= val; | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | const uword new_n_nonzero = m.n_nonzero; | |
| | | | |
| | | access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| const SpSubview<eT>& | | const SpSubview<eT>& | |
| SpSubview<eT>::operator=(const Base<eT, T1>& x) | | SpSubview<eT>::operator=(const Base<eT, T1>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| skipping to change at line 334 | | skipping to change at line 340 | |
| SpSubview<eT>::operator%=(const Base<eT, T1>& x) | | SpSubview<eT>::operator%=(const Base<eT, T1>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| const Proxy<T1> P(x.get_ref()); | | const Proxy<T1> P(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(
), "element-wise multiplication"); | | arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(
), "element-wise multiplication"); | |
| | | | |
| const uword old_n_nonzero = m.n_nonzero; | | const uword old_n_nonzero = m.n_nonzero; | |
| | | | |
|
| for(iterator it(*this); it.pos() < n_nonzero; ++it) | | for(iterator it(*this); it != end(); ++it) | |
| { | | { | |
| (*it) *= P.at(it.row(), it.col()); | | (*it) *= P.at(it.row(), it.col()); | |
|
| if(P.at(it.row(), it.col()) == 0) | | if(P.at(it.row(), it.col()) == eT(0)) | |
| { | | { | |
| it.internal_pos--; | | it.internal_pos--; | |
| } | | } | |
| } | | } | |
| | | | |
| const uword new_n_nonzero = m.n_nonzero; | | const uword new_n_nonzero = m.n_nonzero; | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | |
| | | | |
| return *this; | | return *this; | |
| | | | |
| skipping to change at line 395 | | skipping to change at line 401 | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "insertio
n into sparse submatrix"); | | arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "insertio
n into sparse submatrix"); | |
| | | | |
| const bool alias = ( &m == &(x.m) ); | | const bool alias = ( &m == &(x.m) ); | |
| | | | |
| if(alias == false) | | if(alias == false) | |
| { | | { | |
| const_iterator cit = x.begin(); | | const_iterator cit = x.begin(); | |
| iterator it = begin(); | | iterator it = begin(); | |
| | | | |
|
| while((cit.pos() < x.n_nonzero) || (it.pos() < n_nonzero)) | | while((cit != x.end()) || (it != end())) | |
| { | | { | |
| if((cit.row() == it.row()) && (cit.col() == it.col())) | | if((cit.row() == it.row()) && (cit.col() == it.col())) | |
| { | | { | |
| (*it) = (*cit); | | (*it) = (*cit); | |
| ++it; | | ++it; | |
| ++cit; | | ++cit; | |
| } | | } | |
| else | | else | |
| { | | { | |
| if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row()
> it.row()))) | | if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row()
> it.row()))) | |
| | | | |
| skipping to change at line 451 | | skipping to change at line 457 | |
| | | | |
| const SpProxy<T1> p(x.get_ref()); | | const SpProxy<T1> p(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "insertion into sparse submatrix"); | | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "insertion into sparse submatrix"); | |
| | | | |
| if(p.is_alias(m) == false) | | if(p.is_alias(m) == false) | |
| { | | { | |
| typename SpProxy<T1>::const_iterator_type cit = p.begin(); | | typename SpProxy<T1>::const_iterator_type cit = p.begin(); | |
| iterator it(*this); | | iterator it(*this); | |
| | | | |
|
| while((cit.pos() < p.get_n_nonzero()) || (it.pos() < n_nonzero)) | | while((cit != p.end()) || (it != end())) | |
| { | | { | |
| if(cit == it) // at the same location | | if(cit == it) // at the same location | |
| { | | { | |
| (*it) = (*cit); | | (*it) = (*cit); | |
| ++it; | | ++it; | |
| ++cit; | | ++cit; | |
| } | | } | |
| else | | else | |
| { | | { | |
| if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row()
> it.row()))) | | if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row()
> it.row()))) | |
| | | | |
| skipping to change at line 477 | | skipping to change at line 483 | |
| } | | } | |
| else | | else | |
| { | | { | |
| // it is "ahead" | | // it is "ahead" | |
| at(cit.row(), cit.col()) = (*cit); | | at(cit.row(), cit.col()) = (*cit); | |
| it.internal_pos++; // update iterator so it still works | | it.internal_pos++; // update iterator so it still works | |
| ++cit; | | ++cit; | |
| } | | } | |
| } | | } | |
| } | | } | |
|
| | | | |
| access::rw(n_nonzero) = p.get_n_nonzero(); | | | |
| } | | } | |
| else | | else | |
| { | | { | |
| const SpMat<eT> tmp(p.Q); | | const SpMat<eT> tmp(p.Q); | |
| | | | |
| (*this).operator=(tmp); | | (*this).operator=(tmp); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 505 | | skipping to change at line 509 | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| const SpProxy<T1> p(x.get_ref()); | | const SpProxy<T1> p(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "addition"); | | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "addition"); | |
| | | | |
| if(p.is_alias(m) == false) | | if(p.is_alias(m) == false) | |
| { | | { | |
| typename SpProxy<T1>::const_iterator_type cit = p.begin(); | | typename SpProxy<T1>::const_iterator_type cit = p.begin(); | |
|
| const uword old_n_nonzero = m.n_nonzero; | | | |
| | | | |
|
| while(cit.pos() < p.get_n_nonzero()) | | while(cit != p.end()) | |
| { | | { | |
| at(cit.row(), cit.col()) += (*cit); | | at(cit.row(), cit.col()) += (*cit); | |
|
| | | | |
| ++cit; | | ++cit; | |
| } | | } | |
|
| | | | |
| const uword new_n_nonzero = m.n_nonzero; | | | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | | |
| } | | } | |
| else | | else | |
| { | | { | |
| const SpMat<eT> tmp(p.Q); | | const SpMat<eT> tmp(p.Q); | |
| | | | |
| (*this).operator+=(tmp); | | (*this).operator+=(tmp); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 544 | | skipping to change at line 542 | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| const SpProxy<T1> p(x.get_ref()); | | const SpProxy<T1> p(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "subtraction"); | | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "subtraction"); | |
| | | | |
| if(p.is_alias(m) == false) | | if(p.is_alias(m) == false) | |
| { | | { | |
| typename SpProxy<T1>::const_iterator_type cit = p.begin(); | | typename SpProxy<T1>::const_iterator_type cit = p.begin(); | |
| | | | |
|
| const uword old_n_nonzero = m.n_nonzero; | | while(cit != p.end()) | |
| | | | |
| while(cit.pos() < p.get_n_nonzero()) | | | |
| { | | { | |
| at(cit.row(), cit.col()) -= (*cit); | | at(cit.row(), cit.col()) -= (*cit); | |
|
| | | | |
| ++cit; | | ++cit; | |
| } | | } | |
|
| | | | |
| const uword new_n_nonzero = m.n_nonzero; | | | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | | |
| } | | } | |
| else | | else | |
| { | | { | |
| const SpMat<eT> tmp(p.Q); | | const SpMat<eT> tmp(p.Q); | |
| | | | |
| (*this).operator-=(tmp); | | (*this).operator-=(tmp); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 601 | | skipping to change at line 592 | |
| | | | |
| const SpProxy<T1> p(x.get_ref()); | | const SpProxy<T1> p(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise multiplication"); | | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise multiplication"); | |
| | | | |
| if(p.is_alias(m) == false) | | if(p.is_alias(m) == false) | |
| { | | { | |
| typename SpProxy<T1>::const_iterator_type cit = p.begin(); | | typename SpProxy<T1>::const_iterator_type cit = p.begin(); | |
| iterator it(*this); | | iterator it(*this); | |
| | | | |
|
| const uword old_n_nonzero = m.n_nonzero; | | while((it != end()) || (cit != p.end())) | |
| | | | |
| while((it.pos() < n_nonzero) || (cit.pos() < p.get_n_nonzero())) | | | |
| { | | { | |
| if((cit.row() == it.row()) && (cit.col() == it.col())) | | if((cit.row() == it.row()) && (cit.col() == it.col())) | |
| { | | { | |
| (*it) *= (*cit); | | (*it) *= (*cit); | |
| ++it; | | ++it; | |
| ++cit; | | ++cit; | |
| } | | } | |
| else | | else | |
| { | | { | |
| if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row()
> it.row()))) | | if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row()
> it.row()))) | |
| | | | |
| skipping to change at line 627 | | skipping to change at line 616 | |
| it.internal_pos--; // update iterator so it still works | | it.internal_pos--; // update iterator so it still works | |
| ++it; | | ++it; | |
| } | | } | |
| else | | else | |
| { | | { | |
| // it is "ahead" | | // it is "ahead" | |
| ++cit; | | ++cit; | |
| } | | } | |
| } | | } | |
| } | | } | |
|
| | | | |
| const uword new_n_nonzero = m.n_nonzero; | | | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | | |
| } | | } | |
| else | | else | |
| { | | { | |
| const SpMat<eT> tmp(p.Q); | | const SpMat<eT> tmp(p.Q); | |
| | | | |
| (*this).operator%=(tmp); | | (*this).operator%=(tmp); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 657 | | skipping to change at line 642 | |
| SpSubview<eT>::operator/=(const SpBase<eT, T1>& x) | | SpSubview<eT>::operator/=(const SpBase<eT, T1>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| SpProxy<T1> p(x.get_ref()); | | SpProxy<T1> p(x.get_ref()); | |
| | | | |
| arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise division"); | | arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(
), "element-wise division"); | |
| | | | |
| if(p.is_alias(m) == false) | | if(p.is_alias(m) == false) | |
| { | | { | |
|
| const uword old_n_nonzero = p.get_n_nonzero(); | | | |
| | | | |
| for(uword col = 0; col < n_cols; ++col) | | for(uword col = 0; col < n_cols; ++col) | |
| for(uword row = 0; row < n_rows; ++row) | | for(uword row = 0; row < n_rows; ++row) | |
| { | | { | |
| at(row,col) /= p.at(row,col); | | at(row,col) /= p.at(row,col); | |
| } | | } | |
|
| | | | |
| const uword new_n_nonzero = p.get_n_nonzero(); | | | |
| | | | |
| access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero); | | | |
| } | | } | |
| else | | else | |
| { | | { | |
| const SpMat<eT> tmp(p.Q); | | const SpMat<eT> tmp(p.Q); | |
| | | | |
| (*this).operator/=(tmp); | | (*this).operator/=(tmp); | |
| } | | } | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| skipping to change at line 701 | | skipping to change at line 680 | |
| const uword end_row = aux_row1 + n_rows; | | const uword end_row = aux_row1 + n_rows; | |
| const uword start_col = aux_col1; | | const uword start_col = aux_col1; | |
| const uword end_col = aux_col1 + n_cols; | | const uword end_col = aux_col1 + n_cols; | |
| | | | |
| // iterate over our part of the sparse matrix | | // iterate over our part of the sparse matrix | |
| for(uword col = start_col; col < end_col; ++col) | | for(uword col = start_col; col < end_col; ++col) | |
| for(uword row = start_row; row < end_row; ++row) | | for(uword row = start_row; row < end_row; ++row) | |
| { | | { | |
| access::rw(m).at(row, col) = val; | | access::rw(m).at(row, col) = val; | |
| } | | } | |
|
| | | | |
| access::rw(n_nonzero) = n_elem; | | | |
| } | | } | |
| else | | else | |
| { | | { | |
| (*this).zeros(); | | (*this).zeros(); | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpSubview<eT>::zeros() | | SpSubview<eT>::zeros() | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // we can be a little smarter here | | // we can be a little smarter here | |
| iterator it(*this); | | iterator it(*this); | |
| | | | |
|
| while(it.pos() < n_nonzero) | | while(it != end()) | |
| { | | { | |
|
| (*it) = 0; | | (*it) = eT(0); | |
| it.internal_pos--; // hack to update iterator without requiring a new o
ne | | it.internal_pos--; // hack to update iterator without requiring a new o
ne | |
| ++it; | | ++it; | |
| } | | } | |
|
| | | | |
| access::rw(n_nonzero) = 0; | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpSubview<eT>::ones() | | SpSubview<eT>::ones() | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| (*this).fill(eT(1)); | | (*this).fill(eT(1)); | |
| | | | |
| skipping to change at line 757 | | skipping to change at line 732 | |
| // clear other things | | // clear other things | |
| (*this).zeros(); | | (*this).zeros(); | |
| | | | |
| // now the diagonal ones | | // now the diagonal ones | |
| const uword end_index = std::min(n_rows, n_cols); | | const uword end_index = std::min(n_rows, n_cols); | |
| | | | |
| for(uword ind = 0; ind < end_index; ++ind) | | for(uword ind = 0; ind < end_index; ++ind) | |
| { | | { | |
| m.at(ind + aux_row1, ind + aux_col1) = eT(1); | | m.at(ind + aux_row1, ind + aux_col1) = eT(1); | |
| } | | } | |
|
| | | | |
| access::rw(n_nonzero) = end_index; | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_hot | | arma_hot | |
| inline | | inline | |
| SpValProxy<SpSubview<eT> > | | SpValProxy<SpSubview<eT> > | |
| SpSubview<eT>::operator[](const uword i) | | SpSubview<eT>::operator[](const uword i) | |
| { | | { | |
| const uword row = i % n_rows; | | const uword row = i % n_rows; | |
| const uword col = i / n_rows; | | const uword col = i / n_rows; | |
| | | | |
| skipping to change at line 1037 | | skipping to change at line 1010 | |
| SpSubview<eT>::begin_row() const | | SpSubview<eT>::begin_row() const | |
| { | | { | |
| return const_row_iterator(*this); | | return const_row_iterator(*this); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::iterator | | typename SpSubview<eT>::iterator | |
| SpSubview<eT>::end() | | SpSubview<eT>::end() | |
| { | | { | |
|
| return iterator(*this, n_nonzero); | | return iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::const_iterator | | typename SpSubview<eT>::const_iterator | |
| SpSubview<eT>::end() const | | SpSubview<eT>::end() const | |
| { | | { | |
|
| return const_iterator(*this, n_nonzero); | | return const_iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzer
o); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpSubview<eT>::row_iterator | | typename SpSubview<eT>::row_iterator | |
| SpSubview<eT>::end_row() | | SpSubview<eT>::end_row() | |
| { | | { | |
| return row_iterator(*this, n_nonzero); | | return row_iterator(*this, n_nonzero); | |
| } | | } | |
| | | | |
| | | | |
End of changes. 28 change blocks. |
| 47 lines changed or deleted | | 20 lines changed or added | |
|