| Mat_bones.hpp | | Mat_bones.hpp | |
| // Copyright (C) 2008-2014 Conrad Sanderson | | // Copyright (C) 2008-2014 Conrad Sanderson | |
| // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | |
|
| // Copyright (C) 2012 Ryan Curtin | | // Copyright (C) 2012-2014 Ryan Curtin | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup Mat | | //! \addtogroup Mat | |
| //! @{ | | //! @{ | |
| | | | |
| //! Dense matrix class | | //! Dense matrix class | |
| | | | |
| | | | |
| skipping to change at line 472 | | skipping to change at line 472 | |
| inline void operator--(int); | | inline void operator--(int); | |
| | | | |
| inline bool operator!=(const const_row_iterator& X) const; | | inline bool operator!=(const const_row_iterator& X) const; | |
| inline bool operator==(const const_row_iterator& X) const; | | inline bool operator==(const const_row_iterator& X) const; | |
| | | | |
| arma_aligned const Mat<eT>& M; | | arma_aligned const Mat<eT>& M; | |
| arma_aligned uword row; | | arma_aligned uword row; | |
| arma_aligned uword col; | | arma_aligned uword col; | |
| }; | | }; | |
| | | | |
|
| | | class const_row_col_iterator; | |
| | | | |
| | | class row_col_iterator | |
| | | { | |
| | | public: | |
| | | | |
| | | inline row_col_iterator(); | |
| | | inline row_col_iterator(const row_col_iterator& in_it); | |
| | | inline row_col_iterator(Mat<eT>& in_M, const uword row = 0, const uword | |
| | | col = 0); | |
| | | | |
| | | inline arma_hot eT& operator*(); | |
| | | | |
| | | inline arma_hot row_col_iterator& operator++(); | |
| | | inline arma_hot row_col_iterator operator++(int); | |
| | | inline arma_hot row_col_iterator& operator--(); | |
| | | inline arma_hot row_col_iterator operator--(int); | |
| | | | |
| | | inline uword row() const; | |
| | | inline uword col() const; | |
| | | | |
| | | inline arma_hot bool operator==(const row_col_iterator& rhs) cons | |
| | | t; | |
| | | inline arma_hot bool operator!=(const row_col_iterator& rhs) cons | |
| | | t; | |
| | | inline arma_hot bool operator==(const const_row_col_iterator& rhs) cons | |
| | | t; | |
| | | inline arma_hot bool operator!=(const const_row_col_iterator& rhs) cons | |
| | | t; | |
| | | | |
| | | // So that we satisfy the STL iterator types. | |
| | | typedef std::bidirectional_iterator_tag iterator_category; | |
| | | typedef eT value_type; | |
| | | typedef uword difference_type; // not certain | |
| | | on this one | |
| | | typedef const eT* pointer; | |
| | | typedef const eT& reference; | |
| | | | |
| | | arma_aligned Mat<eT>* M; | |
| | | | |
| | | arma_aligned eT* current_pos; | |
| | | arma_aligned uword internal_col; | |
| | | arma_aligned uword internal_row; | |
| | | }; | |
| | | | |
| | | class const_row_col_iterator | |
| | | { | |
| | | public: | |
| | | | |
| | | inline const_row_col_iterator(); | |
| | | inline const_row_col_iterator(const row_col_iterator& in_it); | |
| | | inline const_row_col_iterator(const const_row_col_iterator& in_it); | |
| | | inline const_row_col_iterator(const Mat<eT>& in_M, const uword row = 0, | |
| | | const uword col = 0); | |
| | | | |
| | | inline arma_hot const eT& operator*() const; | |
| | | | |
| | | inline arma_hot const_row_col_iterator& operator++(); | |
| | | inline arma_hot const_row_col_iterator operator++(int); | |
| | | inline arma_hot const_row_col_iterator& operator--(); | |
| | | inline arma_hot const_row_col_iterator operator--(int); | |
| | | | |
| | | inline uword row() const; | |
| | | inline uword col() const; | |
| | | | |
| | | inline arma_hot bool operator==(const const_row_col_iterator& rhs) cons | |
| | | t; | |
| | | inline arma_hot bool operator!=(const const_row_col_iterator& rhs) cons | |
| | | t; | |
| | | inline arma_hot bool operator==(const row_col_iterator& rhs) cons | |
| | | t; | |
| | | inline arma_hot bool operator!=(const row_col_iterator& rhs) cons | |
| | | t; | |
| | | | |
| | | // So that we satisfy the STL iterator types. | |
| | | typedef std::bidirectional_iterator_tag iterator_category; | |
| | | typedef eT value_type; | |
| | | typedef uword difference_type; // not certain | |
| | | on this one | |
| | | typedef const eT* pointer; | |
| | | typedef const eT& reference; | |
| | | | |
| | | arma_aligned const Mat<eT>* M; | |
| | | | |
| | | arma_aligned const eT* current_pos; | |
| | | arma_aligned uword internal_col; | |
| | | arma_aligned uword internal_row; | |
| | | }; | |
| | | | |
| inline iterator begin(); | | inline iterator begin(); | |
| inline const_iterator begin() const; | | inline const_iterator begin() const; | |
| inline const_iterator cbegin() const; | | inline const_iterator cbegin() const; | |
| | | | |
| inline iterator end(); | | inline iterator end(); | |
| inline const_iterator end() const; | | inline const_iterator end() const; | |
| inline const_iterator cend() const; | | inline const_iterator cend() const; | |
| | | | |
| inline col_iterator begin_col(const uword col_num); | | inline col_iterator begin_col(const uword col_num); | |
| inline const_col_iterator begin_col(const uword col_num) const; | | inline const_col_iterator begin_col(const uword col_num) const; | |
| | | | |
| inline col_iterator end_col (const uword col_num); | | inline col_iterator end_col (const uword col_num); | |
| inline const_col_iterator end_col (const uword col_num) const; | | inline const_col_iterator end_col (const uword col_num) const; | |
| | | | |
| inline row_iterator begin_row(const uword row_num); | | inline row_iterator begin_row(const uword row_num); | |
| inline const_row_iterator begin_row(const uword row_num) const; | | inline const_row_iterator begin_row(const uword row_num) const; | |
| | | | |
| inline row_iterator end_row (const uword row_num); | | inline row_iterator end_row (const uword row_num); | |
| inline const_row_iterator end_row (const uword row_num) const; | | inline const_row_iterator end_row (const uword row_num) const; | |
| | | | |
|
| | | inline row_col_iterator begin_row_col(); | |
| | | inline const_row_col_iterator begin_row_col() const; | |
| | | | |
| | | inline row_col_iterator end_row_col(); | |
| | | inline const_row_col_iterator end_row_col() const; | |
| | | | |
| inline void clear(); | | inline void clear(); | |
| inline bool empty() const; | | inline bool empty() const; | |
| inline uword size() const; | | inline uword size() const; | |
| | | | |
| inline void swap(Mat& B); | | inline void swap(Mat& B); | |
| | | | |
| inline void steal_mem(Mat& X); //!< don't use this unless you're writing
code internal to Armadillo | | inline void steal_mem(Mat& X); //!< don't use this unless you're writing
code internal to Armadillo | |
| | | | |
| inline void steal_mem_col(Mat& X, const uword max_n_rows); | | inline void steal_mem_col(Mat& X, const uword max_n_rows); | |
| | | | |
| | | | |
End of changes. 3 change blocks. |
| 1 lines changed or deleted | | 96 lines changed or added | |
|
| Mat_meat.hpp | | Mat_meat.hpp | |
| // Copyright (C) 2008-2014 Conrad Sanderson | | // Copyright (C) 2008-2014 Conrad Sanderson | |
| // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | |
|
| // Copyright (C) 2012 Ryan Curtin | | // Copyright (C) 2012-2014 Ryan Curtin | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup Mat | | //! \addtogroup Mat | |
| //! @{ | | //! @{ | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| | | | |
| skipping to change at line 906 | | skipping to change at line 906 | |
| //! if memory can't be stolen, copy the given matrix | | //! if memory can't be stolen, copy the given matrix | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| Mat<eT>::steal_mem(Mat<eT>& x) | | Mat<eT>::steal_mem(Mat<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(this != &x) | | if(this != &x) | |
| { | | { | |
|
| const uword x_n_rows = x.n_rows; | | const uword x_n_rows = x.n_rows; | |
| const uword x_n_cols = x.n_cols; | | const uword x_n_cols = x.n_cols; | |
| const uword x_n_elem = x.n_elem; | | const uword x_n_elem = x.n_elem; | |
| const uword x_vec_state = x.vec_state; | | const uhword x_vec_state = x.vec_state; | |
| const uword x_mem_state = x.mem_state; | | const uhword x_mem_state = x.mem_state; | |
| | | | |
|
| const uword t_vec_state = vec_state; | | const uhword t_vec_state = vec_state; | |
| const uword t_mem_state = mem_state; | | const uhword t_mem_state = mem_state; | |
| | | | |
| bool layout_ok = false; | | bool layout_ok = false; | |
| | | | |
| if(t_vec_state == x_vec_state) | | if(t_vec_state == x_vec_state) | |
| { | | { | |
| layout_ok = true; | | layout_ok = true; | |
| } | | } | |
| else | | else | |
| { | | { | |
| if( (t_vec_state == 1) && (x_n_cols == 1) ) { layout_ok = true; } | | if( (t_vec_state == 1) && (x_n_cols == 1) ) { layout_ok = true; } | |
| | | | |
| skipping to change at line 957 | | skipping to change at line 957 | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| Mat<eT>::steal_mem_col(Mat<eT>& x, const uword max_n_rows) | | Mat<eT>::steal_mem_col(Mat<eT>& x, const uword max_n_rows) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const uword x_n_elem = x.n_elem; | | const uword x_n_elem = x.n_elem; | |
| const uword x_mem_state = x.mem_state; | | const uhword x_mem_state = x.mem_state; | |
| | | | |
|
| const uword t_vec_state = vec_state; | | const uhword t_vec_state = vec_state; | |
| const uword t_mem_state = mem_state; | | const uhword t_mem_state = mem_state; | |
| | | | |
| const uword alt_n_rows = (std::min)(x.n_rows, max_n_rows); | | const uword alt_n_rows = (std::min)(x.n_rows, max_n_rows); | |
| | | | |
| if((x_n_elem == 0) || (alt_n_rows == 0)) | | if((x_n_elem == 0) || (alt_n_rows == 0)) | |
| { | | { | |
| (*this).set_size(0,1); | | (*this).set_size(0,1); | |
| | | | |
| return; | | return; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 5279 | | skipping to change at line 5279 | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_warn_unused | | arma_warn_unused | |
| eT | | eT | |
| Mat<eT>::min() const | | Mat<eT>::min() const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| arma_debug_check( (n_elem == 0), "min(): object has no elements" ); | | arma_debug_check( (n_elem == 0), "Mat::min(): object has no elements" ); | |
| | | | |
| return op_min::direct_min(memptr(), n_elem); | | return op_min::direct_min(memptr(), n_elem); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_warn_unused | | arma_warn_unused | |
| eT | | eT | |
| Mat<eT>::max() const | | Mat<eT>::max() const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| arma_debug_check( (n_elem == 0), "max(): object has no elements" ); | | arma_debug_check( (n_elem == 0), "Mat::max(): object has no elements" ); | |
| | | | |
| return op_max::direct_max(memptr(), n_elem); | | return op_max::direct_max(memptr(), n_elem); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| eT | | eT | |
| Mat<eT>::min(uword& index_of_min_val) const | | Mat<eT>::min(uword& index_of_min_val) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| arma_debug_check( (n_elem == 0), "min(): object has no elements" ); | | arma_debug_check( (n_elem == 0), "Mat::min(): object has no elements" ); | |
| | | | |
| return op_min::direct_min(memptr(), n_elem, index_of_min_val); | | return op_min::direct_min(memptr(), n_elem, index_of_min_val); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| eT | | eT | |
| Mat<eT>::max(uword& index_of_max_val) const | | Mat<eT>::max(uword& index_of_max_val) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| arma_debug_check( (n_elem == 0), "max(): object has no elements" ); | | arma_debug_check( (n_elem == 0), "Mat::max(): object has no elements" ); | |
| | | | |
| return op_max::direct_max(memptr(), n_elem, index_of_max_val); | | return op_max::direct_max(memptr(), n_elem, index_of_max_val); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| eT | | eT | |
| Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const | | Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| arma_debug_check( (n_elem == 0), "min(): object has no elements" ); | | arma_debug_check( (n_elem == 0), "Mat::min(): object has no elements" ); | |
| | | | |
| uword iq; | | uword iq; | |
| | | | |
| eT val = op_min::direct_min(memptr(), n_elem, iq); | | eT val = op_min::direct_min(memptr(), n_elem, iq); | |
| | | | |
| row_of_min_val = iq % n_rows; | | row_of_min_val = iq % n_rows; | |
| col_of_min_val = iq / n_rows; | | col_of_min_val = iq / n_rows; | |
| | | | |
| return val; | | return val; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| eT | | eT | |
| Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const | | Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| arma_debug_check( (n_elem == 0), "max(): object has no elements" ); | | arma_debug_check( (n_elem == 0), "Mat::max(): object has no elements" ); | |
| | | | |
| uword iq; | | uword iq; | |
| | | | |
| eT val = op_max::direct_max(memptr(), n_elem, iq); | | eT val = op_max::direct_max(memptr(), n_elem, iq); | |
| | | | |
| row_of_max_val = iq % n_rows; | | row_of_max_val = iq % n_rows; | |
| col_of_max_val = iq / n_rows; | | col_of_max_val = iq / n_rows; | |
| | | | |
| return val; | | return val; | |
| } | | } | |
| | | | |
| skipping to change at line 5821 | | skipping to change at line 5821 | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| bool | | bool | |
| Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_i
terator& X) const | | Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_i
terator& X) const | |
| { | | { | |
| return ( (row == X.row) && (col == X.col) ) ? true : false; | | return ( (row == X.row) && (col == X.col) ) ? true : false; | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | Mat<eT>::row_col_iterator::row_col_iterator() | |
| | | : M (NULL) | |
| | | , current_pos (NULL) | |
| | | , internal_col(0 ) | |
| | | , internal_row(0 ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | // Technically this iterator is invalid (it does not point to a real elem | |
| | | ent) | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | Mat<eT>::row_col_iterator::row_col_iterator(const row_col_iterator& in_it) | |
| | | : M (in_it.M ) | |
| | | , current_pos (in_it.current_pos ) | |
| | | , internal_col(in_it.internal_col) | |
| | | , internal_row(in_it.internal_row) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | Mat<eT>::row_col_iterator::row_col_iterator(Mat<eT>& in_M, const uword row, | |
| | | const uword col) | |
| | | : M (&in_M ) | |
| | | , current_pos (&in_M.at(row,col)) | |
| | | , internal_col(col ) | |
| | | , internal_row(row ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | eT& | |
| | | Mat<eT>::row_col_iterator::operator*() | |
| | | { | |
| | | return *current_pos; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::row_col_iterator& | |
| | | Mat<eT>::row_col_iterator::operator++() | |
| | | { | |
| | | current_pos++; | |
| | | internal_row++; | |
| | | | |
| | | // Check to see if we moved a column. | |
| | | if(internal_row == M->n_rows) | |
| | | { | |
| | | internal_col++; | |
| | | internal_row = 0; | |
| | | } | |
| | | | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::row_col_iterator | |
| | | Mat<eT>::row_col_iterator::operator++(int) | |
| | | { | |
| | | typename Mat<eT>::row_col_iterator temp(*this); | |
| | | | |
| | | ++(*this); | |
| | | | |
| | | return temp; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline typename Mat<eT>::row_col_iterator& | |
| | | Mat<eT>::row_col_iterator::operator--() | |
| | | { | |
| | | if(internal_row > 0) | |
| | | { | |
| | | current_pos--; | |
| | | internal_row--; | |
| | | } | |
| | | else | |
| | | if(internal_col > 0) | |
| | | { | |
| | | current_pos--; | |
| | | internal_col--; | |
| | | internal_row = M->n_rows - 1; | |
| | | } | |
| | | | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::row_col_iterator | |
| | | Mat<eT>::row_col_iterator::operator--(int) | |
| | | { | |
| | | typename Mat<eT>::row_col_iterator temp(*this); | |
| | | | |
| | | --(*this); | |
| | | | |
| | | return temp; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | uword | |
| | | Mat<eT>::row_col_iterator::row() const | |
| | | { | |
| | | return internal_row; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | uword | |
| | | Mat<eT>::row_col_iterator::col() const | |
| | | { | |
| | | return internal_col; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::row_col_iterator::operator==(const row_col_iterator& rhs) const | |
| | | { | |
| | | return (current_pos == rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::row_col_iterator::operator!=(const row_col_iterator& rhs) const | |
| | | { | |
| | | return (current_pos != rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::row_col_iterator::operator==(const const_row_col_iterator& rhs) co | |
| | | nst | |
| | | { | |
| | | return (current_pos == rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::row_col_iterator::operator!=(const const_row_col_iterator& rhs) co | |
| | | nst | |
| | | { | |
| | | return (current_pos != rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | Mat<eT>::const_row_col_iterator::const_row_col_iterator() | |
| | | : M (NULL) | |
| | | , current_pos (NULL) | |
| | | , internal_col(0 ) | |
| | | , internal_row(0 ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | // Technically this iterator is invalid (it does not point to a real elem | |
| | | ent) | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | Mat<eT>::const_row_col_iterator::const_row_col_iterator(const row_col_itera | |
| | | tor& in_it) | |
| | | : M (in_it.M ) | |
| | | , current_pos (in_it.current_pos) | |
| | | , internal_col(in_it.col() ) | |
| | | , internal_row(in_it.row() ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | Mat<eT>::const_row_col_iterator::const_row_col_iterator(const const_row_col | |
| | | _iterator& in_it) | |
| | | : M (in_it.M ) | |
| | | , current_pos (in_it.current_pos) | |
| | | , internal_col(in_it.col() ) | |
| | | , internal_row(in_it.row() ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | Mat<eT>::const_row_col_iterator::const_row_col_iterator(const Mat<eT>& in_M | |
| | | , const uword row, const uword col) | |
| | | : M (&in_M ) | |
| | | , current_pos (&in_M.at(row,col)) | |
| | | , internal_col(col ) | |
| | | , internal_row(row ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | const eT& | |
| | | Mat<eT>::const_row_col_iterator::operator*() const | |
| | | { | |
| | | return *current_pos; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::const_row_col_iterator& | |
| | | Mat<eT>::const_row_col_iterator::operator++() | |
| | | { | |
| | | current_pos++; | |
| | | internal_row++; | |
| | | | |
| | | // Check to see if we moved a column. | |
| | | if(internal_row == M->n_rows) | |
| | | { | |
| | | internal_col++; | |
| | | internal_row = 0; | |
| | | } | |
| | | | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::const_row_col_iterator | |
| | | Mat<eT>::const_row_col_iterator::operator++(int) | |
| | | { | |
| | | typename Mat<eT>::const_row_col_iterator temp(*this); | |
| | | | |
| | | ++(*this); | |
| | | | |
| | | return temp; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::const_row_col_iterator& | |
| | | Mat<eT>::const_row_col_iterator::operator--() | |
| | | { | |
| | | if(internal_row > 0) | |
| | | { | |
| | | current_pos--; | |
| | | internal_row--; | |
| | | } | |
| | | else | |
| | | if(internal_col > 0) | |
| | | { | |
| | | current_pos--; | |
| | | internal_col--; | |
| | | internal_row = M->n_rows - 1; | |
| | | } | |
| | | | |
| | | return *this; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::const_row_col_iterator | |
| | | Mat<eT>::const_row_col_iterator::operator--(int) | |
| | | { | |
| | | typename Mat<eT>::const_row_col_iterator temp(*this); | |
| | | | |
| | | --(*this); | |
| | | | |
| | | return temp; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | uword | |
| | | Mat<eT>::const_row_col_iterator::row() const | |
| | | { | |
| | | return internal_row; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | uword | |
| | | Mat<eT>::const_row_col_iterator::col() const | |
| | | { | |
| | | return internal_col; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::const_row_col_iterator::operator==(const const_row_col_iterator& r | |
| | | hs) const | |
| | | { | |
| | | return (current_pos == rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::const_row_col_iterator::operator!=(const const_row_col_iterator& r | |
| | | hs) const | |
| | | { | |
| | | return (current_pos != rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::const_row_col_iterator::operator==(const row_col_iterator& rhs) co | |
| | | nst | |
| | | { | |
| | | return (current_pos == rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | bool | |
| | | Mat<eT>::const_row_col_iterator::operator!=(const row_col_iterator& rhs) co | |
| | | nst | |
| | | { | |
| | | return (current_pos != rhs.current_pos); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| typename Mat<eT>::iterator | | typename Mat<eT>::iterator | |
| Mat<eT>::begin() | | Mat<eT>::begin() | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| return memptr(); | | return memptr(); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| | | | |
| skipping to change at line 5975 | | skipping to change at line 6291 | |
| typename Mat<eT>::const_row_iterator | | typename Mat<eT>::const_row_iterator | |
| Mat<eT>::end_row(const uword row_num) const | | Mat<eT>::end_row(const uword row_num) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of boun
ds" ); | | arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of boun
ds" ); | |
| | | | |
| return typename Mat<eT>::const_row_iterator(*this, row_num + 1); | | return typename Mat<eT>::const_row_iterator(*this, row_num + 1); | |
| } | | } | |
| | | | |
|
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::row_col_iterator | |
| | | Mat<eT>::begin_row_col() | |
| | | { | |
| | | return row_col_iterator(*this); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename Mat<eT>::const_row_col_iterator | |
| | | Mat<eT>::begin_row_col() const | |
| | | { | |
| | | return const_row_col_iterator(*this); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline typename Mat<eT>::row_col_iterator | |
| | | Mat<eT>::end_row_col() | |
| | | { | |
| | | return row_col_iterator(*this, 0, n_cols); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline typename Mat<eT>::const_row_col_iterator | |
| | | Mat<eT>::end_row_col() const | |
| | | { | |
| | | return const_row_col_iterator(*this, 0, n_cols); | |
| | | } | |
| | | | |
| //! resets this matrix to an empty matrix | | //! resets this matrix to an empty matrix | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| Mat<eT>::clear() | | Mat<eT>::clear() | |
| { | | { | |
| reset(); | | reset(); | |
| } | | } | |
| | | | |
| //! returns true if the matrix has no elements | | //! returns true if the matrix has no elements | |
| | | | |
End of changes. 13 change blocks. |
| 18 lines changed or deleted | | 376 lines changed or added | |
|
| SpMat_bones.hpp | | SpMat_bones.hpp | |
|
| // Copyright (C) 2011-2013 Ryan Curtin | | // Copyright (C) 2011-2014 Ryan Curtin | |
| // Copyright (C) 2012-2014 Conrad Sanderson | | // Copyright (C) 2012-2014 Conrad Sanderson | |
| // Copyright (C) 2011 Matthew Amidon | | // Copyright (C) 2011 Matthew Amidon | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup SpMat | | //! \addtogroup SpMat | |
| //! @{ | | //! @{ | |
| | | | |
| | | | |
| skipping to change at line 39 | | skipping to change at line 39 | |
| const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector | | const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector | |
| | | | |
| // So that SpValProxy can call add_element() and delete_element(). | | // So that SpValProxy can call add_element() and delete_element(). | |
| friend class SpValProxy<SpMat<eT> >; | | friend class SpValProxy<SpMat<eT> >; | |
| friend class SpSubview<eT>; | | friend class SpSubview<eT>; | |
| | | | |
| /** | | /** | |
| * 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. The length of this array is n_nonzero + 1; t | | * and the column pointers. | |
| he | | * | |
| * final value ensures the integrity of iterators. If you are planning o | | * The length of this array is (n_nonzero + 1); the final value ensures | |
| n | | * the integrity of iterators. If you are planning on resizing this vect | |
| * resizing this vector, it's probably best to use mem_resize() instead. | | or, | |
| | | * it's probably best to use mem_resize() instead, which automatically se | |
| | | ts | |
| | | * the length to (n_nonzero + 1). If you need to allocate the memory you | |
| | | rself | |
| | | * for some reason, be sure to set values[n_nonzero] to 0. | |
| */ | | */ | |
| 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. If you are planning on resizing this vector, | | * The length of this array is (n_nonzero + 1); the final value ensures | |
| it's | | * the integrity of iterators. If you are planning on resizing this vect | |
| * probably best to use mem_resize() instead. | | or, | |
| | | * it's probably best to use mem_resize() instead. If you need to alloca | |
| | | te | |
| | | * the memory yourself for some reason, be sure to set row_indices[n_nonz | |
| | | ero] to 0. | |
| */ | | */ | |
| 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]]. This array is of length (n_cols + 2); t | | * the row indicated by row_indices[col_ptrs[i]]. | |
| he | | * | |
| * element col_ptrs[n_cols] should be equal to n_nonzero, and the element | | * This array is of length (n_cols + 2); the element col_ptrs[n_cols] sho | |
| * col_ptrs[n_cols + 1] is an invalid very large value that ensures the | | uld | |
| * integrity of iterators. | | * be equal to n_nonzero, and the element col_ptrs[n_cols + 1] is an inva | |
| | | lid | |
| | | * very large value that ensures the integrity of iterators. | |
| | | * | |
| | | * The col_ptrs array is set by the init() function (which is called by t | |
| | | he | |
| | | * constructors and set_size() and other functions that set the size of t | |
| | | he | |
| | | * matrix), so allocating col_ptrs by hand should not be necessary. | |
| */ | | */ | |
| const uword* const col_ptrs; | | const uword* const col_ptrs; | |
| | | | |
| inline SpMat(); //! Size will be 0x0 (empty). | | inline SpMat(); //! Size will be 0x0 (empty). | |
| inline ~SpMat(); | | inline ~SpMat(); | |
| | | | |
| inline SpMat(const uword in_rows, const uword in_cols); | | inline SpMat(const uword in_rows, const uword in_cols); | |
| | | | |
| inline SpMat(const char* text); | | inline SpMat(const char* text); | |
| inline const SpMat& operator=(const char* text); | | inline const SpMat& operator=(const char* text); | |
| inline SpMat(const std::string& text); | | inline SpMat(const std::string& text); | |
| inline const SpMat& operator=(const std::string& text); | | inline const SpMat& operator=(const std::string& text); | |
| inline SpMat(const SpMat<eT>& x); | | inline SpMat(const SpMat<eT>& x); | |
| | | | |
| #if defined(ARMA_USE_CXX11) | | #if defined(ARMA_USE_CXX11) | |
| inline SpMat(SpMat&& m); | | inline SpMat(SpMat&& m); | |
| inline const SpMat& operator=(SpMat&& m); | | inline const SpMat& operator=(SpMat&& m); | |
| #endif | | #endif | |
| | | | |
|
| template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc | | template<typename T1, typename T2, typename T3> | |
| ations, const Base<eT,T2>& values, const bool sort_locations = true); | | inline SpMat(const Base<uword,T1>& rowind, const Base<uword,T2>& colptr, | |
| template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc | | const Base<eT,T3>& values, const uword n_rows, const uword n_cols); | |
| ations, const Base<eT,T2>& values, const uword n_rows, const uword n_cols, | | | |
| const bool sort_locations = true, const bool check_for_zeros = true); | | | |
| | | | |
|
| template<typename T1, typename T2, typename T3> inline SpMat(const Base<u | | template<typename T1, typename T2> | |
| word,T1>& rowind, const Base<uword,T2>& colptr, const Base<eT,T3>& values, | | inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values, | |
| const uword n_rows, const uword n_cols); | | const bool sort_locations = true); | |
| | | | |
| | | template<typename T1, typename T2> | |
| | | inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values, | |
| | | const uword n_rows, const uword n_cols, const bool sort_locations = true, c | |
| | | onst bool check_for_zeros = true); | |
| | | | |
| | | template<typename T1, typename T2> | |
| | | inline SpMat(const bool add_values, const Base<uword,T1>& locations, cons | |
| | | t Base<eT,T2>& values, const uword n_rows, const uword n_cols, const bool s | |
| | | ort_locations = true, const bool check_for_zeros = true); | |
| | | | |
| inline const SpMat& operator=(const eT val); //! Sets size to 1x1. | | inline const SpMat& operator=(const eT val); //! Sets size to 1x1. | |
| inline const SpMat& operator*=(const eT val); | | inline const SpMat& operator*=(const eT val); | |
| inline const SpMat& operator/=(const eT val); | | inline const SpMat& operator/=(const eT val); | |
| // operator+=(val) and operator-=(val) are not defined as they don't make
sense for sparse matrices | | // operator+=(val) and operator-=(val) are not defined as they don't make
sense for sparse matrices | |
| | | | |
| /** | | /** | |
| * Operators on other sparse matrices. These work as though you would ex
pect. | | * Operators on other sparse matrices. These work as though you would ex
pect. | |
| */ | | */ | |
| inline const SpMat& operator=(const SpMat& m); | | inline const SpMat& operator=(const SpMat& m); | |
| | | | |
| skipping to change at line 305 | | skipping to change at line 323 | |
| | | | |
| inline const SpMat& speye(); | | inline const SpMat& speye(); | |
| inline const SpMat& speye(const uword in_rows, const uword in_cols); | | inline const SpMat& speye(const uword in_rows, const uword in_cols); | |
| | | | |
| inline const SpMat& sprandu(const uword in_rows, const uword in_cols, con
st double density); | | inline const SpMat& sprandu(const uword in_rows, const uword in_cols, con
st double density); | |
| | | | |
| inline const SpMat& sprandn(const uword in_rows, const uword in_cols, con
st double density); | | inline const SpMat& sprandn(const uword in_rows, const uword in_cols, con
st double density); | |
| | | | |
| inline void reset(); | | inline void reset(); | |
| | | | |
|
| /** | | | |
| * Get the minimum or maximum of the matrix. | | | |
| */ | | | |
| inline arma_warn_unused eT min() const; | | | |
| inline eT min(uword& index_of_min_val) const; | | | |
| inline eT min(uword& row_of_min_val, uword& col_of_min_v | | | |
| al) const; | | | |
| | | | |
| inline arma_warn_unused eT max() const; | | | |
| inline eT max(uword& index_of_max_val) const; | | | |
| inline eT max(uword& row_of_min_val, uword& col_of_min_v | | | |
| al) const; | | | |
| | | | |
| // saving and loading | | // saving and loading | |
| | | | |
| inline bool save(const std::string name, const file_type type = arma_bi
nary, const bool print_status = true) const; | | inline bool save(const std::string name, const file_type type = arma_bi
nary, const bool print_status = true) const; | |
| inline bool save( std::ostream& os, const file_type type = arma_bi
nary, const bool print_status = true) const; | | inline bool save( std::ostream& os, const file_type type = arma_bi
nary, const bool print_status = true) const; | |
| | | | |
| inline bool load(const std::string name, const file_type type = arma_bi
nary, const bool print_status = true); | | inline bool load(const std::string name, const file_type type = arma_bi
nary, const bool print_status = true); | |
| inline bool load( std::istream& is, const file_type type = arma_bi
nary, const bool print_status = true); | | inline bool load( std::istream& is, const file_type type = arma_bi
nary, const bool print_status = true); | |
| | | | |
| inline bool quiet_save(const std::string name, const file_type type = a
rma_binary) const; | | inline bool quiet_save(const std::string name, const file_type type = a
rma_binary) const; | |
| inline bool quiet_save( std::ostream& os, const file_type type = a
rma_binary) const; | | inline bool quiet_save( std::ostream& os, const file_type type = a
rma_binary) const; | |
| | | | |
| skipping to change at line 347 | | skipping to change at line 354 | |
| class const_iterator; | | class const_iterator; | |
| class row_iterator; | | class row_iterator; | |
| class const_row_iterator; | | class const_row_iterator; | |
| | | | |
| // Iterator base provides basic operators but not how to compare or how t
o | | // Iterator base provides basic operators but not how to compare or how t
o | |
| // iterate. | | // iterate. | |
| class iterator_base | | class iterator_base | |
| { | | { | |
| public: | | public: | |
| | | | |
|
| | | inline iterator_base(); | |
| 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 arma_hot eT operator*() const; | | inline arma_hot eT operator*() 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; | |
| | | | |
| // So that we satisfy the STL iterator types. | | // So that we satisfy the STL iterator types. | |
| typedef std::bidirectional_iterator_tag iterator_category; | | typedef std::bidirectional_iterator_tag iterator_category; | |
| typedef eT value_type; | | typedef eT value_type; | |
| typedef uword difference_type; // not certain
on this one | | typedef uword difference_type; // not certain
on this one | |
| typedef const eT* pointer; | | typedef const eT* pointer; | |
| typedef const eT& reference; | | typedef const eT& reference; | |
| }; | | }; | |
| | | | |
| class const_iterator : public iterator_base | | class const_iterator : public iterator_base | |
| { | | { | |
| public: | | public: | |
| | | | |
|
| | | inline const_iterator(); | |
| 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. | | //! 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 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 arma_hot const_iterator& operator++(); | | inline arma_hot const_iterator& operator++(); | |
| inline arma_hot const_iterator operator++(int); | | inline arma_hot const_iterator operator++(int); | |
| | | | |
| | | | |
| skipping to change at line 409 | | skipping to change at line 418 | |
| /** | | /** | |
| * 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() : const_iterator() { } | |
| 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(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 arma_hot SpValProxy<SpMat<eT> > operator*(); | | inline arma_hot SpValProxy<SpMat<eT> > operator*(); | |
| | | | |
| // overloads needed for return type correctness | | // overloads needed for return type correctness | |
| inline arma_hot iterator& operator++(); | | inline arma_hot iterator& operator++(); | |
| inline arma_hot iterator operator++(int); | | inline arma_hot iterator operator++(int); | |
| | | | |
| skipping to change at line 433 | | skipping to change at line 443 | |
| // This has a different value_type than iterator_base. | | // This has a different value_type than iterator_base. | |
| typedef SpValProxy<SpMat<eT> > value_type; | | typedef SpValProxy<SpMat<eT> > value_type; | |
| typedef const SpValProxy<SpMat<eT> >* pointer; | | typedef const SpValProxy<SpMat<eT> >* pointer; | |
| typedef const SpValProxy<SpMat<eT> >& reference; | | typedef const SpValProxy<SpMat<eT> >& reference; | |
| }; | | }; | |
| | | | |
| class const_row_iterator : public iterator_base | | class const_row_iterator : public iterator_base | |
| { | | { | |
| public: | | public: | |
| | | | |
|
| | | inline const_row_iterator(); | |
| 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 arma_hot const_row_iterator& operator++(); | | inline arma_hot const_row_iterator& operator++(); | |
| inline arma_hot const_row_iterator operator++(int); | | inline arma_hot const_row_iterator operator++(int); | |
| | | | |
| inline arma_hot const_row_iterator& operator--(); | | inline arma_hot const_row_iterator& operator--(); | |
| inline arma_hot const_row_iterator operator--(int); | | inline arma_hot const_row_iterator 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[actu
al_pos]; } | |
| | | | |
| arma_inline uword row() const { return internal_row; } | | arma_inline uword row() const { return internal_row; } | |
| | | | |
| inline arma_hot bool operator==(const const_iterator& rhs) const; | | inline arma_hot bool operator==(const const_iterator& rhs) const; | |
| inline arma_hot bool operator!=(const const_iterator& rhs) const; | | inline arma_hot bool operator!=(const const_iterator& rhs) const; | |
| | | | |
| inline arma_hot bool operator==(const typename SpSubview<eT>::const_ite
rator& rhs) const; | | inline arma_hot bool operator==(const typename SpSubview<eT>::const_ite
rator& rhs) const; | |
| inline arma_hot bool operator!=(const typename SpSubview<eT>::const_ite
rator& rhs) const; | | inline arma_hot bool operator!=(const typename SpSubview<eT>::const_ite
rator& rhs) const; | |
| | | | |
| inline arma_hot bool operator==(const const_row_iterator& rhs) const; | | inline arma_hot bool operator==(const const_row_iterator& rhs) const; | |
| inline arma_hot bool operator!=(const const_row_iterator& rhs) const; | | inline arma_hot bool operator!=(const const_row_iterator& rhs) const; | |
| | | | |
| inline arma_hot bool operator==(const typename SpSubview<eT>::const_row
_iterator& rhs) const; | | inline arma_hot bool operator==(const typename SpSubview<eT>::const_row
_iterator& rhs) const; | |
| inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row
_iterator& rhs) const; | | inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row
_iterator& rhs) const; | |
| }; | | }; | |
| | | | |
| class row_iterator : public const_row_iterator | | class row_iterator : public const_row_iterator | |
| { | | { | |
| public: | | public: | |
| | | | |
|
| | | inline row_iterator() : const_row_iterator() {} | |
| 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 arma_hot SpValProxy<SpMat<eT> > operator*(); | | inline arma_hot SpValProxy<SpMat<eT> > operator*(); | |
| | | | |
| // overloads required for return type correctness | | // overloads required for return type correctness | |
| inline arma_hot row_iterator& operator++(); | | inline arma_hot row_iterator& operator++(); | |
| inline arma_hot row_iterator operator++(int); | | inline arma_hot row_iterator operator++(int); | |
| | | | |
| inline arma_hot row_iterator& operator--(); | | inline arma_hot row_iterator& operator--(); | |
| inline arma_hot row_iterator operator--(int); | | inline arma_hot row_iterator operator--(int); | |
| | | | |
| // This has a different value_type than iterator_base. | | // This has a different value_type than iterator_base. | |
| typedef SpValProxy<SpMat<eT> > value_type; | | typedef SpValProxy<SpMat<eT> > value_type; | |
| typedef const SpValProxy<SpMat<eT> >* pointer; | | typedef const SpValProxy<SpMat<eT> >* pointer; | |
| typedef const SpValProxy<SpMat<eT> >& reference; | | typedef const SpValProxy<SpMat<eT> >& reference; | |
| }; | | }; | |
| | | | |
|
| | | typedef iterator row_col_iterator; | |
| | | typedef const_iterator const_row_col_iterator; | |
| | | | |
| 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; | |
| | | | |
| inline row_iterator end_row(); | | inline row_iterator end_row(); | |
| inline const_row_iterator end_row() const; | | inline const_row_iterator end_row() const; | |
| | | | |
| inline row_iterator end_row(const uword row_num); | | inline row_iterator end_row(const uword row_num); | |
| inline const_row_iterator end_row(const uword row_num) const; | | inline const_row_iterator end_row(const uword row_num) const; | |
| | | | |
|
| | | inline row_col_iterator begin_row_col(); | |
| | | inline const_row_col_iterator begin_row_col() const; | |
| | | | |
| | | inline row_col_iterator end_row_col(); | |
| | | inline const_row_col_iterator end_row_col() const; | |
| | | | |
| inline void clear(); | | inline void clear(); | |
| inline bool empty() const; | | inline bool empty() const; | |
| inline uword size() const; | | inline uword size() const; | |
| | | | |
| /** | | /** | |
| * Resize memory. You are responsible for updating the column pointers a
nd | | * Resize memory. You are responsible for updating the column pointers a
nd | |
| * filling the new memory (if the new size is larger). If the new size i
s | | * filling the new memory (if the new size is larger). If the new size i
s | |
| * smaller, the first new_n_nonzero elements will be copied. n_nonzero i
s | | * smaller, the first new_n_nonzero elements will be copied. n_nonzero i
s | |
| * updated. | | * updated. | |
| */ | | */ | |
| | | | |
| skipping to change at line 546 | | skipping to change at line 567 | |
| * Initialize the matrix from text. Data is (of course) not preserved, a
nd | | * Initialize the matrix from text. Data is (of course) not preserved, a
nd | |
| * the size will be reset. | | * the size will be reset. | |
| */ | | */ | |
| inline void init(const std::string& text); | | inline void init(const std::string& text); | |
| | | | |
| /** | | /** | |
| * Initialize from another matrix (copy). | | * Initialize from another matrix (copy). | |
| */ | | */ | |
| inline void init(const SpMat& x); | | inline void init(const SpMat& x); | |
| | | | |
|
| inline void init_batch(const Mat<uword>& locations, const Mat<eT>& values | | inline void init_batch_std(const Mat<uword>& locations, const Mat<eT>& va | |
| , const bool sort_locations); | | lues, const bool sort_locations); | |
| | | inline void init_batch_add(const Mat<uword>& locations, const Mat<eT>& va | |
| | | lues, const bool sort_locations); | |
| | | | |
| private: | | private: | |
| | | | |
| /** | | /** | |
| * Return the given element. | | * Return the given element. | |
| */ | | */ | |
| inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u
word i); | | inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u
word i); | |
| inline arma_hot arma_warn_unused eT get_value(const u
word i) const; | | inline arma_hot arma_warn_unused eT get_value(const u
word i) const; | |
| | | | |
| inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u
word in_row, const uword in_col); | | inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const u
word in_row, const uword in_col); | |
| | | | |
End of changes. 19 change blocks. |
| 45 lines changed or deleted | | 73 lines changed or added | |
|
| SpMat_iterators_meat.hpp | | SpMat_iterators_meat.hpp | |
|
| // Copyright (C) 2011-2012 Ryan Curtin | | // Copyright (C) 2011-2014 Ryan Curtin | |
| | | // Copyright (C) 2012-2014 Conrad Sanderson | |
| // Copyright (C) 2011 Matthew Amidon | | // Copyright (C) 2011 Matthew Amidon | |
|
| // Copyright (C) 2012 Conrad Sanderson | | | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup SpMat | | //! \addtogroup SpMat | |
| //! @{ | | //! @{ | |
| | | | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| // SpMat::iterator_base implementation
// | | // SpMat::iterator_base implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | SpMat<eT>::iterator_base::iterator_base() | |
| | | : M(NULL) | |
| | | , internal_col(0) | |
| | | , internal_pos(0) | |
| | | { | |
| | | // Technically this iterator is invalid (it may not point to a real eleme | |
| | | nt) | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M) | | SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M) | |
|
| : M(in_M) | | : M(&in_M) | |
| , internal_col(0) | | , internal_col(0) | |
| , internal_pos(0) | | , internal_pos(0) | |
| { | | { | |
| // Technically this iterator is invalid (it may not point to a real eleme
nt) | | // Technically this iterator is invalid (it may not point to a real eleme
nt) | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword
in_col, const uword in_pos) | | SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword
in_col, const uword in_pos) | |
|
| : M(in_M) | | : M(&in_M) | |
| , internal_col(in_col) | | , internal_col(in_col) | |
| , internal_pos(in_pos) | | , internal_pos(in_pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_hot | | 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]; | |
| } | | } | |
| | | | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| // SpMat::const_iterator implementation
// | | // SpMat::const_iterator implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | SpMat<eT>::const_iterator::const_iterator() | |
| | | : iterator_base() | |
| | | { | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | 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. | | // Corner case for empty matrices. | |
| if(in_M.n_nonzero == 0) | | if(in_M.n_nonzero == 0) | |
| { | | { | |
| iterator_base::internal_col = in_M.n_cols; | | iterator_base::internal_col = in_M.n_cols; | |
| return; | | 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] <= iter
ator_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) | |
| : iterator_base(in_M, in_col, 0) | | : iterator_base(in_M, in_col, 0) | |
| { | | { | |
| // So we have a position we want to be right after. Skip to the column. | | // So we have a position we want to be right after. Skip to the column. | |
|
| iterator_base::internal_pos = iterator_base::M.col_ptrs[iterator_base::in
ternal_col]; | | iterator_base::internal_pos = iterator_base::M->col_ptrs[iterator_base::i
nternal_col]; | |
| | | | |
| // Now we have to make sure that is the right column. | | // Now we have to make sure that is the right column. | |
|
| 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] <= iter
ator_base::internal_pos) | |
| { | | { | |
| iterator_base::internal_col++; | | iterator_base::internal_col++; | |
| } | | } | |
| | | | |
| // 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_ro
w) && (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) | | 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) | | : iterator_base(in_M, in_col, in_pos) | |
| { | | { | |
| // Nothing to do. | | // Nothing to do. | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | 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 | | 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; | |
| } | | } | |
| | | | |
| // Check to see if we moved a column. | | // Check to see if we moved a column. | |
|
| 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] <= ite
rator_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 | | arma_hot | |
| | | | |
| skipping to change at line 156 | | skipping to change at line 173 | |
| { | | { | |
| //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_
base::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> | |
| | | | |
| skipping to change at line 262 | | skipping to change at line 279 | |
| // SpMat::iterator implementation
// | | // SpMat::iterator implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_hot | | 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 | | 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; | |
| | | | |
| skipping to change at line 321 | | skipping to change at line 338 | |
| return tmp; | | return tmp; | |
| } | | } | |
| | | | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| // SpMat::const_row_iterator implementation
// | | // SpMat::const_row_iterator implementation
// | |
| ///////////////////////////////////////////////////////////////////////////
//// | | ///////////////////////////////////////////////////////////////////////////
//// | |
| | | | |
| /** | | /** | |
| * Initialize the const_row_iterator. | | * Initialize the const_row_iterator. | |
| */ | | */ | |
|
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | SpMat<eT>::const_row_iterator::const_row_iterator() | |
| | | : iterator_base() | |
| | | , internal_row(0) | |
| | | , actual_pos(0) | |
| | | { | |
| | | } | |
| | | | |
| 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. | | // Corner case for empty matrix. | |
| if(in_M.n_nonzero == 0) | | if(in_M.n_nonzero == 0) | |
| { | | { | |
| | | | |
| skipping to change at line 344 | | skipping to change at line 371 | |
| } | | } | |
| | | | |
| // We don't count zeros in our position count, so we have to find the non
zero | | // We don't count zeros in our position count, so we have to find the non
zero | |
| // 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 = std::numeric_limits<uword>::max(); // Invalid value. | |
| uword cur_row = 0; | | uword cur_row = 0; | |
| uword cur_col = 0; | | uword cur_col = 0; | |
| | | | |
| while(true) // This loop is terminated from the inside. | | while(true) // This loop is terminated from the inside. | |
| { | | { | |
| // Is there anything in the column we are looking at? | | // Is there anything in the column we are looking at? | |
|
| for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterat
or_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator
_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++) | | for (uword ind = 0; ((iterator_base::M->col_ptrs[cur_col] + ind < itera
tor_base::M->col_ptrs[cur_col + 1]) && (iterator_base::M->row_indices[itera
tor_base::M->col_ptrs[cur_col] + ind] <= cur_row)); ind++) | |
| { | | { | |
| // There is something in this column. Is it in the row we are lookin
g at? | | // There is something in this column. Is it in the row we are lookin
g at? | |
|
| const uword row_index = iterator_base::M.row_indices[iterator_base::M
.col_ptrs[cur_col] + ind]; | | const uword row_index = iterator_base::M->row_indices[iterator_base::
M->col_ptrs[cur_col] + ind]; | |
| if (row_index == cur_row) | | if (row_index == cur_row) | |
| { | | { | |
| // Yes, it is what we are looking for. Increment our current posit
ion. | | // Yes, it is what we are looking for. Increment our current posit
ion. | |
| if (++cur_pos == iterator_base::internal_pos) | | if (++cur_pos == iterator_base::internal_pos) | |
| { | | { | |
|
| actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; | | actual_pos = iterator_base::M->col_ptrs[cur_col] + ind; | |
| internal_row = cur_row; | | internal_row = cur_row; | |
| iterator_base::internal_col = cur_col; | | iterator_base::internal_col = cur_col; | |
| | | | |
| return; | | return; | |
| } | | } | |
| | | | |
| // We are done with this column. Break to the column incrementing
code (directly below). | | // We are done with this column. Break to the column incrementing
code (directly below). | |
| break; | | break; | |
| } | | } | |
| else if(row_index > cur_row) | | else if(row_index > cur_row) | |
| { | | { | |
| break; // Can't be in this column. | | break; // Can't be in this column. | |
| } | | } | |
| } | | } | |
| | | | |
| cur_col++; // Done with the column. Move on. | | cur_col++; // Done with the column. Move on. | |
|
| if (cur_col == iterator_base::M.n_cols) | | if (cur_col == iterator_base::M->n_cols) | |
| { | | { | |
| // We are out of columns. Loop back to the beginning and look on the | | // We are out of columns. Loop back to the beginning and look on the | |
| // next row. | | // next row. | |
| cur_col = 0; | | cur_col = 0; | |
| cur_row++; | | cur_row++; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 415 | | skipping to change at line 442 | |
| internal_row = it.internal_row; | | internal_row = it.internal_row; | |
| actual_pos = it.actual_pos; | | actual_pos = it.actual_pos; | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Initialize the const_row_iterator from another const_row_iterator. | | * Initialize the const_row_iterator from another const_row_iterator. | |
| */ | | */ | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| SpMat<eT>::const_row_iterator::const_row_iterator(const typename SpMat<eT>:
:const_row_iterator& other) | | SpMat<eT>::const_row_iterator::const_row_iterator(const typename SpMat<eT>:
:const_row_iterator& other) | |
|
| : iterator_base(other.M, other.internal_col, other.internal_pos) | | : iterator_base(*other.M, other.internal_col, other.internal_pos) | |
| , internal_row(other.internal_row) | | , internal_row(other.internal_row) | |
| , 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 | | 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; | |
|
| actual_pos = iterator_base::M.n_nonzero; | | actual_pos = iterator_base::M->n_nonzero; | |
| | | | |
| return *this; | | return *this; | |
| } | | } | |
| | | | |
| // Otherwise, we need to search. | | // Otherwise, we need to search. | |
| 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. | |
| { | | { | |
| // Increment the current column and see if we are now on a new row. | | // Increment the current column and see if we are now on a new row. | |
|
| if (++cur_col == iterator_base::M.n_cols) | | if (++cur_col == iterator_base::M->n_cols) | |
| { | | { | |
| cur_col = 0; | | cur_col = 0; | |
| cur_row++; | | cur_row++; | |
| } | | } | |
| | | | |
| // Is there anything in this new column? | | // Is there anything in this new column? | |
|
| for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterat
or_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator
_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++) | | for (uword ind = 0; ((iterator_base::M->col_ptrs[cur_col] + ind < itera
tor_base::M->col_ptrs[cur_col + 1]) && (iterator_base::M->row_indices[itera
tor_base::M->col_ptrs[cur_col] + ind] <= cur_row)); ind++) | |
| { | | { | |
|
| if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] +
ind] == cur_row) | | if (iterator_base::M->row_indices[iterator_base::M->col_ptrs[cur_col]
+ ind] == cur_row) | |
| { | | { | |
| // We have successfully incremented. | | // We have successfully incremented. | |
| internal_row = cur_row; | | internal_row = cur_row; | |
| iterator_base::internal_col = cur_col; | | iterator_base::internal_col = cur_col; | |
|
| actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; | | actual_pos = iterator_base::M->col_ptrs[cur_col] + ind; | |
| | | | |
| return *this; // Now we are done. | | return *this; // Now we are done. | |
| } | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Increment the row_iterator (but do not return anything. | | * Increment the row_iterator (but do not return anything. | |
| */ | | */ | |
| | | | |
| skipping to change at line 506 | | skipping to change at line 533 | |
| { | | { | |
| 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. | |
| { | | { | |
| // Decrement the current column and see if we are now on a new row. Th
is is a uword so a negativity check won't work. | | // Decrement the current column and see if we are now on a new row. Th
is is a uword so a negativity check won't work. | |
|
| if (--cur_col > iterator_base::M.n_cols /* this means it underflew */) | | if (--cur_col > iterator_base::M->n_cols /* this means it underflew */) | |
| { | | { | |
|
| cur_col = iterator_base::M.n_cols - 1; | | cur_col = iterator_base::M->n_cols - 1; | |
| cur_row--; | | cur_row--; | |
| } | | } | |
| | | | |
| // Is there anything in this new column? | | // Is there anything in this new column? | |
|
| for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterat
or_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator
_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++) | | for (uword ind = 0; ((iterator_base::M->col_ptrs[cur_col] + ind < itera
tor_base::M->col_ptrs[cur_col + 1]) && (iterator_base::M->row_indices[itera
tor_base::M->col_ptrs[cur_col] + ind] <= cur_row)); ind++) | |
| { | | { | |
|
| if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] +
ind] == cur_row) | | if (iterator_base::M->row_indices[iterator_base::M->col_ptrs[cur_col]
+ ind] == cur_row) | |
| { | | { | |
| // We have successfully decremented. | | // We have successfully decremented. | |
| iterator_base::internal_col = cur_col; | | iterator_base::internal_col = cur_col; | |
| internal_row = cur_row; | | internal_row = cur_row; | |
|
| actual_pos = iterator_base::M.col_ptrs[cur_col] + ind; | | actual_pos = iterator_base::M->col_ptrs[cur_col] + ind; | |
| | | | |
| return *this; // Now we are done. | | return *this; // Now we are done. | |
| } | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| /** | | /** | |
| * Decrement the row_iterator. | | * Decrement the row_iterator. | |
| */ | | */ | |
| | | | |
| skipping to change at line 629 | | skipping to change at line 656 | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| arma_hot | | 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 | | 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; | |
| | | | |
End of changes. 38 change blocks. |
| 37 lines changed or deleted | | 65 lines changed or added | |
|
| SpMat_meat.hpp | | SpMat_meat.hpp | |
|
| // Copyright (C) 2011-2013 Ryan Curtin | | // Copyright (C) 2011-2014 Ryan Curtin | |
| // Copyright (C) 2012-2014 Conrad Sanderson | | // Copyright (C) 2012-2014 Conrad Sanderson | |
| // Copyright (C) 2011 Matthew Amidon | | // Copyright (C) 2011 Matthew Amidon | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup SpMat | | //! \addtogroup SpMat | |
| //! @{ | | //! @{ | |
| | | | |
| | | | |
| skipping to change at line 243 | | skipping to change at line 243 | |
| { | | { | |
| filtered_vals[index] = vals[i]; | | filtered_vals[index] = vals[i]; | |
| | | | |
| filtered_locs.at(0, index) = locs.at(0, i); | | filtered_locs.at(0, index) = locs.at(0, i); | |
| filtered_locs.at(1, index) = locs.at(1, i); | | filtered_locs.at(1, index) = locs.at(1, i); | |
| | | | |
| ++index; | | ++index; | |
| } | | } | |
| } | | } | |
| | | | |
|
| init_batch(filtered_locs, filtered_vals, sort_locations); | | init_batch_std(filtered_locs, filtered_vals, sort_locations); | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| init_batch(locs, vals, sort_locations); | | init_batch_std(locs, vals, sort_locations); | |
| } | | } | |
| } | | } | |
| | | | |
| //! Insert a large number of values at once. | | //! Insert a large number of values at once. | |
| //! locations.row[0] should be row indices, locations.row[1] should be colu
mn indices, | | //! locations.row[0] should be row indices, locations.row[1] should be colu
mn indices, | |
| //! and values should be the corresponding values. | | //! and values should be the corresponding values. | |
| //! If sort_locations is false, then it is assumed that the locations and v
alues | | //! If sort_locations is false, then it is assumed that the locations and v
alues | |
| //! are already sorted in column-major ordering. | | //! are already sorted in column-major ordering. | |
| //! In this constructor the size is explicitly given. | | //! In this constructor the size is explicitly given. | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 314 | | skipping to change at line 314 | |
| { | | { | |
| filtered_vals[index] = vals[i]; | | filtered_vals[index] = vals[i]; | |
| | | | |
| filtered_locs.at(0, index) = locs.at(0, i); | | filtered_locs.at(0, index) = locs.at(0, i); | |
| filtered_locs.at(1, index) = locs.at(1, i); | | filtered_locs.at(1, index) = locs.at(1, i); | |
| | | | |
| ++index; | | ++index; | |
| } | | } | |
| } | | } | |
| | | | |
|
| init_batch(filtered_locs, filtered_vals, sort_locations); | | init_batch_std(filtered_locs, filtered_vals, sort_locations); | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| init_batch(locs, vals, sort_locations); | | init_batch_std(locs, vals, sort_locations); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| init_batch(locs, vals, sort_locations); | | init_batch_std(locs, vals, sort_locations); | |
| | | } | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | template<typename T1, typename T2> | |
| | | inline | |
| | | SpMat<eT>::SpMat(const bool add_values, const Base<uword,T1>& locations_exp | |
| | | r, const Base<eT,T2>& vals_expr, const uword in_n_rows, const uword in_n_co | |
| | | ls, const bool sort_locations, const bool check_for_zeros) | |
| | | : n_rows(0) | |
| | | , n_cols(0) | |
| | | , n_elem(0) | |
| | | , n_nonzero(0) | |
| | | , vec_state(0) | |
| | | , values(NULL) | |
| | | , row_indices(NULL) | |
| | | , col_ptrs(NULL) | |
| | | { | |
| | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| | | const unwrap<T1> locs_tmp( locations_expr.get_ref() ); | |
| | | const unwrap<T2> vals_tmp( vals_expr.get_ref() ); | |
| | | | |
| | | const Mat<uword>& locs = locs_tmp.M; | |
| | | const Mat<eT>& vals = vals_tmp.M; | |
| | | | |
| | | arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'v | |
| | | alues' object is not a vector" ); | |
| | | arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): location | |
| | | s matrix must have two rows" ); | |
| | | arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number o | |
| | | f locations is different than number of values" ); | |
| | | | |
| | | init(in_n_rows, in_n_cols); | |
| | | | |
| | | // Ensure that there are no zeros, unless the user asked not to. | |
| | | if(check_for_zeros) | |
| | | { | |
| | | const uword N_old = vals.n_elem; | |
| | | uword N_new = 0; | |
| | | | |
| | | for(uword i = 0; i < N_old; ++i) | |
| | | { | |
| | | if(vals[i] != eT(0)) { ++N_new; } | |
| | | } | |
| | | | |
| | | if(N_new != N_old) | |
| | | { | |
| | | Col<eT> filtered_vals(N_new); | |
| | | Mat<uword> filtered_locs(2, N_new); | |
| | | | |
| | | uword index = 0; | |
| | | for(uword i = 0; i < N_old; ++i) | |
| | | { | |
| | | if(vals[i] != eT(0)) | |
| | | { | |
| | | filtered_vals[index] = vals[i]; | |
| | | | |
| | | filtered_locs.at(0, index) = locs.at(0, i); | |
| | | filtered_locs.at(1, index) = locs.at(1, i); | |
| | | | |
| | | ++index; | |
| | | } | |
| | | } | |
| | | | |
| | | add_values ? init_batch_add(filtered_locs, filtered_vals, sort_locati | |
| | | ons) : init_batch_std(filtered_locs, filtered_vals, sort_locations); | |
| | | } | |
| | | else | |
| | | { | |
| | | add_values ? init_batch_add(locs, vals, sort_locations) : init_batch_ | |
| | | std(locs, vals, sort_locations); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | add_values ? init_batch_add(locs, vals, sort_locations) : init_batch_st | |
| | | d(locs, vals, sort_locations); | |
| } | | } | |
| } | | } | |
| | | | |
| //! Insert a large number of values at once. | | //! Insert a large number of values at once. | |
| //! Per CSC format, rowind_expr should be row indices, | | //! Per CSC format, rowind_expr should be row indices, | |
| //! colptr_expr should column ptr indices locations, | | //! colptr_expr should column ptr indices locations, | |
| //! and values should be the corresponding values. | | //! and values should be the corresponding values. | |
| //! In this constructor the size is explicitly given. | | //! In this constructor the size is explicitly given. | |
| //! Values are assumed to be sorted, and the size | | //! Values are assumed to be sorted, and the size | |
| //! information is trusted | | //! information is trusted | |
| | | | |
| skipping to change at line 3099 | | skipping to change at line 3169 | |
| case 1: | | case 1: | |
| init(0, 1); | | init(0, 1); | |
| break; | | break; | |
| | | | |
| case 2: | | case 2: | |
| init(1, 0); | | init(1, 0); | |
| break; | | break; | |
| } | | } | |
| } | | } | |
| | | | |
|
| /** | | | |
| * Get the minimum or the maximum of the matrix. | | | |
| */ | | | |
| template<typename eT> | | | |
| inline | | | |
| arma_warn_unused | | | |
| eT | | | |
| SpMat<eT>::min() const | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_check((n_elem == 0), "min(): object has no elements"); | | | |
| | | | |
| if (n_nonzero == 0) | | | |
| { | | | |
| return 0; | | | |
| } | | | |
| | | | |
| eT val = op_min::direct_min(values, n_nonzero); | | | |
| | | | |
| if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less. | | | |
| { | | | |
| val = 0; | | | |
| } | | | |
| | | | |
| return val; | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| eT | | | |
| SpMat<eT>::min(uword& index_of_min_val) const | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_check((n_elem == 0), "min(): object has no elements"); | | | |
| | | | |
| eT val = 0; | | | |
| | | | |
| if (n_nonzero == 0) // There are no other elements. It must be 0. | | | |
| { | | | |
| index_of_min_val = 0; | | | |
| } | | | |
| else | | | |
| { | | | |
| uword location; | | | |
| val = op_min::direct_min(values, n_nonzero, location); | | | |
| | | | |
| if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less. | | | |
| { | | | |
| val = 0; | | | |
| | | | |
| // Give back the index to the first zero position. | | | |
| index_of_min_val = 0; | | | |
| while (get_position(index_of_min_val) == index_of_min_val) // An elem | | | |
| ent exists at that position. | | | |
| { | | | |
| index_of_min_val++; | | | |
| } | | | |
| | | | |
| } | | | |
| else | | | |
| { | | | |
| index_of_min_val = get_position(location); | | | |
| } | | | |
| } | | | |
| | | | |
| return val; | | | |
| | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| eT | | | |
| SpMat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_check((n_elem == 0), "min(): object has no elements"); | | | |
| | | | |
| eT val = 0; | | | |
| | | | |
| if (n_nonzero == 0) // There are no other elements. It must be 0. | | | |
| { | | | |
| row_of_min_val = 0; | | | |
| col_of_min_val = 0; | | | |
| } | | | |
| else | | | |
| { | | | |
| uword location; | | | |
| val = op_min::direct_min(values, n_nonzero, location); | | | |
| | | | |
| if ((val > 0) && (n_nonzero < n_elem)) // A sparse 0 is less. | | | |
| { | | | |
| val = 0; | | | |
| | | | |
| location = 0; | | | |
| while (get_position(location) == location) // An element exists at th | | | |
| at position. | | | |
| { | | | |
| location++; | | | |
| } | | | |
| | | | |
| row_of_min_val = location % n_rows; | | | |
| col_of_min_val = location / n_rows; | | | |
| } | | | |
| else | | | |
| { | | | |
| get_position(location, row_of_min_val, col_of_min_val); | | | |
| } | | | |
| } | | | |
| | | | |
| return val; | | | |
| | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| arma_warn_unused | | | |
| eT | | | |
| SpMat<eT>::max() const | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_check((n_elem == 0), "max(): object has no elements"); | | | |
| | | | |
| if (n_nonzero == 0) | | | |
| { | | | |
| return 0; | | | |
| } | | | |
| | | | |
| eT val = op_max::direct_max(values, n_nonzero); | | | |
| | | | |
| if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more. | | | |
| { | | | |
| return 0; | | | |
| } | | | |
| | | | |
| return val; | | | |
| | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| eT | | | |
| SpMat<eT>::max(uword& index_of_max_val) const | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_check((n_elem == 0), "max(): object has no elements"); | | | |
| | | | |
| eT val = 0; | | | |
| | | | |
| if (n_nonzero == 0) | | | |
| { | | | |
| index_of_max_val = 0; | | | |
| } | | | |
| else | | | |
| { | | | |
| uword location; | | | |
| val = op_max::direct_max(values, n_nonzero, location); | | | |
| | | | |
| if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more. | | | |
| { | | | |
| val = 0; | | | |
| | | | |
| location = 0; | | | |
| while (get_position(location) == location) // An element exists at th | | | |
| at position. | | | |
| { | | | |
| location++; | | | |
| } | | | |
| | | | |
| } | | | |
| else | | | |
| { | | | |
| index_of_max_val = get_position(location); | | | |
| } | | | |
| | | | |
| } | | | |
| | | | |
| return val; | | | |
| | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| eT | | | |
| SpMat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| arma_debug_check((n_elem == 0), "max(): object has no elements"); | | | |
| | | | |
| eT val = 0; | | | |
| | | | |
| if (n_nonzero == 0) | | | |
| { | | | |
| row_of_max_val = 0; | | | |
| col_of_max_val = 0; | | | |
| } | | | |
| else | | | |
| { | | | |
| uword location; | | | |
| val = op_max::direct_max(values, n_nonzero, location); | | | |
| | | | |
| if ((val < 0) && (n_nonzero < n_elem)) // A sparse 0 is more. | | | |
| { | | | |
| val = 0; | | | |
| | | | |
| location = 0; | | | |
| while (get_position(location) == location) // An element exists at th | | | |
| at position. | | | |
| { | | | |
| location++; | | | |
| } | | | |
| | | | |
| row_of_max_val = location % n_rows; | | | |
| col_of_max_val = location / n_rows; | | | |
| | | | |
| } | | | |
| else | | | |
| { | | | |
| get_position(location, row_of_max_val, col_of_max_val); | | | |
| } | | | |
| | | | |
| } | | | |
| | | | |
| return val; | | | |
| | | | |
| } | | | |
| | | | |
| //! save the matrix to a file | | //! save the matrix to a file | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| bool | | bool | |
| SpMat<eT>::save(const std::string name, const file_type type, const bool pr
int_status) const | | SpMat<eT>::save(const std::string name, const file_type type, const bool pr
int_status) const | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| bool save_okay; | | bool save_okay; | |
| | | | |
| | | | |
| skipping to change at line 3774 | | skipping to change at line 3616 | |
| arrayops::copy(access::rwp(row_indices), x.row_indices, x.n_nonzero + 1
); | | 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>::init_batch(const Mat<uword>& locs, const Mat<eT>& vals, const bo
ol sort_locations) | | SpMat<eT>::init_batch_std(const Mat<uword>& locs, const Mat<eT>& vals, cons
t bool sort_locations) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| // Resize to correct number of elements. | | // Resize to correct number of elements. | |
| mem_resize(vals.n_elem); | | mem_resize(vals.n_elem); | |
| | | | |
| // Reset column pointers to zero. | | // Reset column pointers to zero. | |
| arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1); | | arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1); | |
| | | | |
| bool actually_sorted = true; | | bool actually_sorted = true; | |
| | | | |
| skipping to change at line 3821 | | skipping to change at line 3663 | |
| abslocs[i] = locs_i[1] * n_rows + locs_i[0]; | | abslocs[i] = locs_i[1] * n_rows + locs_i[0]; | |
| } | | } | |
| | | | |
| uvec sorted_indices = sort_index(abslocs); // Ascending sort. | | uvec sorted_indices = sort_index(abslocs); // Ascending sort. | |
| | | | |
| // Now we add the elements in this sorted order. | | // Now we add the elements in this sorted order. | |
| for (uword i = 0; i < sorted_indices.n_elem; ++i) | | for (uword i = 0; i < sorted_indices.n_elem; ++i) | |
| { | | { | |
| const uword* locs_i = locs.colptr( sorted_indices[i] ); | | const uword* locs_i = locs.colptr( sorted_indices[i] ); | |
| | | | |
|
| arma_debug_check | | arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) | |
| ( | | ), "SpMat::SpMat(): invalid row or column index" ); | |
| ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ), | | | |
| "SpMat::SpMat(): invalid row or column index" | | | |
| ); | | | |
| | | | |
| if(i > 0) | | if(i > 0) | |
| { | | { | |
| const uword* locs_im1 = locs.colptr( sorted_indices[i-1] ); | | const uword* locs_im1 = locs.colptr( sorted_indices[i-1] ); | |
| | | | |
|
| arma_debug_check | | arma_debug_check( ( (locs_i[1] == locs_im1[1]) && (locs_i[0] == l | |
| ( | | ocs_im1[0]) ), "SpMat::SpMat(): detected identical locations" ); | |
| ( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) ), | | | |
| "SpMat::SpMat(): two identical point locations in list" | | | |
| ); | | | |
| } | | } | |
| | | | |
| access::rw(values[i]) = vals[ sorted_indices[i] ]; | | access::rw(values[i]) = vals[ sorted_indices[i] ]; | |
| access::rw(row_indices[i]) = locs_i[0]; | | access::rw(row_indices[i]) = locs_i[0]; | |
| | | | |
| access::rw(col_ptrs[ locs_i[1] + 1 ])++; | | access::rw(col_ptrs[ locs_i[1] + 1 ])++; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| if( (sort_locations == false) || (actually_sorted == true) ) | | if( (sort_locations == false) || (actually_sorted == true) ) | |
| { | | { | |
| // Now set the values and row indices correctly. | | // Now set the values and row indices correctly. | |
| // Increment the column pointers in each column (so they are column "co
unts"). | | // Increment the column pointers in each column (so they are column "co
unts"). | |
|
| for (uword i = 0; i < vals.n_elem; ++i) | | for(uword i = 0; i < vals.n_elem; ++i) | |
| { | | { | |
| const uword* locs_i = locs.colptr(i); | | const uword* locs_i = locs.colptr(i); | |
| | | | |
|
| arma_debug_check | | arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ), | |
| ( | | "SpMat::SpMat(): invalid row or column index" ); | |
| ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ), | | | |
| "SpMat::SpMat(): invalid row or column index" | | | |
| ); | | | |
| | | | |
| if(i > 0) | | if(i > 0) | |
| { | | { | |
| const uword* locs_im1 = locs.colptr(i-1); | | const uword* locs_im1 = locs.colptr(i-1); | |
| | | | |
| arma_debug_check | | arma_debug_check | |
| ( | | ( | |
| ( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && loc
s_i[0] < locs_im1[0]) ), | | ( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && loc
s_i[0] < locs_im1[0]) ), | |
| "SpMat::SpMat(): out of order points; either pass sort_locations
= true, or sort points in column-major ordering" | | "SpMat::SpMat(): out of order points; either pass sort_locations
= true, or sort points in column-major ordering" | |
| ); | | ); | |
| | | | |
|
| arma_debug_check | | arma_debug_check( ( (locs_i[1] == locs_im1[1]) && (locs_i[0] == loc | |
| ( | | s_im1[0]) ), "SpMat::SpMat(): detected identical locations" ); | |
| ( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) ), | | | |
| "SpMat::SpMat(): two identical point locations in list" | | | |
| ); | | | |
| } | | } | |
| | | | |
| access::rw(values[i]) = vals[i]; | | access::rw(values[i]) = vals[i]; | |
| access::rw(row_indices[i]) = locs_i[0]; | | access::rw(row_indices[i]) = locs_i[0]; | |
| | | | |
| access::rw(col_ptrs[ locs_i[1] + 1 ])++; | | access::rw(col_ptrs[ locs_i[1] + 1 ])++; | |
| } | | } | |
| } | | } | |
| | | | |
| // Now fix the column pointers. | | // Now fix the column pointers. | |
| for (uword i = 0; i <= n_cols; ++i) | | for (uword i = 0; i <= n_cols; ++i) | |
| { | | { | |
| access::rw(col_ptrs[i + 1]) += col_ptrs[i]; | | access::rw(col_ptrs[i + 1]) += col_ptrs[i]; | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| | | SpMat<eT>::init_batch_add(const Mat<uword>& locs, const Mat<eT>& vals, cons | |
| | | t bool sort_locations) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | if(locs.n_cols < 2) | |
| | | { | |
| | | init_batch_std(locs, vals, false); | |
| | | return; | |
| | | } | |
| | | | |
| | | // Reset column pointers to zero. | |
| | | arrayops::inplace_set(access::rwp(col_ptrs), uword(0), n_cols + 1); | |
| | | | |
| | | bool actually_sorted = true; | |
| | | | |
| | | if(sort_locations == true) | |
| | | { | |
| | | // sort_index() uses std::sort() which may use quicksort... so we bette | |
| | | r | |
| | | // make sure it's not already sorted before taking an O(N^2) sort penal | |
| | | ty. | |
| | | for (uword i = 1; i < locs.n_cols; ++i) | |
| | | { | |
| | | const uword* locs_i = locs.colptr(i ); | |
| | | const uword* locs_im1 = locs.colptr(i-1); | |
| | | | |
| | | if( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && locs_ | |
| | | i[0] <= locs_im1[0]) ) | |
| | | { | |
| | | actually_sorted = false; | |
| | | break; | |
| | | } | |
| | | } | |
| | | | |
| | | if(actually_sorted == false) | |
| | | { | |
| | | // This may not be the fastest possible implementation but it maximiz | |
| | | es code reuse. | |
| | | Col<uword> abslocs(locs.n_cols); | |
| | | | |
| | | for (uword i = 0; i < locs.n_cols; ++i) | |
| | | { | |
| | | const uword* locs_i = locs.colptr(i); | |
| | | | |
| | | abslocs[i] = locs_i[1] * n_rows + locs_i[0]; | |
| | | } | |
| | | | |
| | | uvec sorted_indices = sort_index(abslocs); // Ascending sort. | |
| | | | |
| | | // work out the number of unique elments | |
| | | uword n_unique = 1; // first element is unique | |
| | | | |
| | | for(uword i=1; i < sorted_indices.n_elem; ++i) | |
| | | { | |
| | | const uword* locs_i = locs.colptr( sorted_indices[i ] ); | |
| | | const uword* locs_im1 = locs.colptr( sorted_indices[i-1] ); | |
| | | | |
| | | if( (locs_i[1] != locs_im1[1]) || (locs_i[0] != locs_im1[0]) ) { + | |
| | | +n_unique; } | |
| | | } | |
| | | | |
| | | // resize to correct number of elements | |
| | | mem_resize(n_unique); | |
| | | | |
| | | // Now we add the elements in this sorted order. | |
| | | uword count = 0; | |
| | | | |
| | | // first element | |
| | | { | |
| | | const uword i = 0; | |
| | | const uword* locs_i = locs.colptr( sorted_indices[i] ); | |
| | | | |
| | | arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) | |
| | | ), "SpMat::SpMat(): invalid row or column index" ); | |
| | | | |
| | | access::rw(values[count]) = vals[ sorted_indices[i] ]; | |
| | | access::rw(row_indices[count]) = locs_i[0]; | |
| | | | |
| | | access::rw(col_ptrs[ locs_i[1] + 1 ])++; | |
| | | } | |
| | | | |
| | | for(uword i=1; i < sorted_indices.n_elem; ++i) | |
| | | { | |
| | | const uword* locs_i = locs.colptr( sorted_indices[i ] ); | |
| | | const uword* locs_im1 = locs.colptr( sorted_indices[i-1] ); | |
| | | | |
| | | arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) | |
| | | ), "SpMat::SpMat(): invalid row or column index" ); | |
| | | | |
| | | if( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) ) | |
| | | { | |
| | | access::rw(values[count]) += vals[ sorted_indices[i] ]; | |
| | | } | |
| | | else | |
| | | { | |
| | | count++; | |
| | | access::rw(values[count]) = vals[ sorted_indices[i] ]; | |
| | | access::rw(row_indices[count]) = locs_i[0]; | |
| | | | |
| | | access::rw(col_ptrs[ locs_i[1] + 1 ])++; | |
| | | } | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | if( (sort_locations == false) || (actually_sorted == true) ) | |
| | | { | |
| | | // work out the number of unique elments | |
| | | uword n_unique = 1; // first element is unique | |
| | | | |
| | | for(uword i=1; i < locs.n_cols; ++i) | |
| | | { | |
| | | const uword* locs_i = locs.colptr(i ); | |
| | | const uword* locs_im1 = locs.colptr(i-1); | |
| | | | |
| | | if( (locs_i[1] != locs_im1[1]) || (locs_i[0] != locs_im1[0]) ) { ++n | |
| | | _unique; } | |
| | | } | |
| | | | |
| | | // resize to correct number of elements | |
| | | mem_resize(n_unique); | |
| | | | |
| | | // Now set the values and row indices correctly. | |
| | | // Increment the column pointers in each column (so they are column "co | |
| | | unts"). | |
| | | | |
| | | uword count = 0; | |
| | | | |
| | | // first element | |
| | | { | |
| | | const uword i = 0; | |
| | | const uword* locs_i = locs.colptr(i); | |
| | | | |
| | | arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ), | |
| | | "SpMat::SpMat(): invalid row or column index" ); | |
| | | | |
| | | access::rw(values[count]) = vals[i]; | |
| | | access::rw(row_indices[count]) = locs_i[0]; | |
| | | | |
| | | access::rw(col_ptrs[ locs_i[1] + 1 ])++; | |
| | | } | |
| | | | |
| | | for(uword i=1; i < locs.n_cols; ++i) | |
| | | { | |
| | | const uword* locs_i = locs.colptr(i ); | |
| | | const uword* locs_im1 = locs.colptr(i-1); | |
| | | | |
| | | arma_debug_check( ( (locs_i[0] >= n_rows) || (locs_i[1] >= n_cols) ), | |
| | | "SpMat::SpMat(): invalid row or column index" ); | |
| | | | |
| | | arma_debug_check | |
| | | ( | |
| | | ( (locs_i[1] < locs_im1[1]) || (locs_i[1] == locs_im1[1] && locs_ | |
| | | i[0] < locs_im1[0]) ), | |
| | | "SpMat::SpMat(): out of order points; either pass sort_locations = | |
| | | true, or sort points in column-major ordering" | |
| | | ); | |
| | | | |
| | | if( (locs_i[1] == locs_im1[1]) && (locs_i[0] == locs_im1[0]) ) | |
| | | { | |
| | | access::rw(values[count]) += vals[i]; | |
| | | } | |
| | | else | |
| | | { | |
| | | count++; | |
| | | | |
| | | access::rw(values[count]) = vals[i]; | |
| | | access::rw(row_indices[count]) = locs_i[0]; | |
| | | | |
| | | access::rw(col_ptrs[ locs_i[1] + 1 ])++; | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | // Now fix the column pointers. | |
| | | for (uword i = 0; i <= n_cols; ++i) | |
| | | { | |
| | | access::rw(col_ptrs[i + 1]) += col_ptrs[i]; | |
| | | } | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | 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); | |
| | | | |
| skipping to change at line 4201 | | skipping to change at line 4198 | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| typename SpMat<eT>::const_row_iterator | | typename SpMat<eT>::const_row_iterator | |
| SpMat<eT>::end_row(const uword row_num) const | | SpMat<eT>::end_row(const uword row_num) const | |
| { | | { | |
| return const_row_iterator(*this, row_num + 1, 0); | | return const_row_iterator(*this, row_num + 1, 0); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | typename SpMat<eT>::row_col_iterator | |
| | | SpMat<eT>::begin_row_col() | |
| | | { | |
| | | return begin(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename SpMat<eT>::const_row_col_iterator | |
| | | SpMat<eT>::begin_row_col() const | |
| | | { | |
| | | return begin(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline typename SpMat<eT>::row_col_iterator | |
| | | SpMat<eT>::end_row_col() | |
| | | { | |
| | | return end(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | typename SpMat<eT>::const_row_col_iterator | |
| | | SpMat<eT>::end_row_col() const | |
| | | { | |
| | | return end(); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| void | | void | |
| SpMat<eT>::clear() | | SpMat<eT>::clear() | |
| { | | { | |
| (*this).reset(); | | (*this).reset(); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| bool | | bool | |
| SpMat<eT>::empty() const | | SpMat<eT>::empty() const | |
| | | | |
End of changes. 15 change blocks. |
| 260 lines changed or deleted | | 310 lines changed or added | |
|
| armadillo | | armadillo | |
| | | | |
| skipping to change at line 73 | | skipping to change at line 73 | |
| #include "armadillo_bits/include_atlas.hpp" | | #include "armadillo_bits/include_atlas.hpp" | |
| | | | |
| #if defined(ARMA_USE_HDF5) | | #if defined(ARMA_USE_HDF5) | |
| #include <hdf5.h> | | #include <hdf5.h> | |
| #if defined(H5_USE_16_API_DEFAULT) || defined(H5_USE_16_API) | | #if defined(H5_USE_16_API_DEFAULT) || defined(H5_USE_16_API) | |
| #pragma message ("WARNING: disabling use of HDF5 due to its incompatibl
e configuration") | | #pragma message ("WARNING: disabling use of HDF5 due to its incompatibl
e configuration") | |
| #undef ARMA_USE_HDF5 | | #undef ARMA_USE_HDF5 | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
|
| | | #if defined(_OPENMP) | |
| | | #include <omp.h> | |
| | | #endif | |
| | | | |
| //! \namespace arma namespace for Armadillo classes and functions | | //! \namespace arma namespace for Armadillo classes and functions | |
| namespace arma | | namespace arma | |
| { | | { | |
| | | | |
| // preliminaries | | // preliminaries | |
| | | | |
| #include "armadillo_bits/forward_bones.hpp" | | #include "armadillo_bits/forward_bones.hpp" | |
| #include "armadillo_bits/arma_static_check.hpp" | | #include "armadillo_bits/arma_static_check.hpp" | |
| #include "armadillo_bits/typedef_elem.hpp" | | #include "armadillo_bits/typedef_elem.hpp" | |
| #include "armadillo_bits/typedef_elem_check.hpp" | | #include "armadillo_bits/typedef_elem_check.hpp" | |
| | | | |
| skipping to change at line 228 | | skipping to change at line 232 | |
| #include "armadillo_bits/op_trimat_bones.hpp" | | #include "armadillo_bits/op_trimat_bones.hpp" | |
| #include "armadillo_bits/op_cumsum_bones.hpp" | | #include "armadillo_bits/op_cumsum_bones.hpp" | |
| #include "armadillo_bits/op_symmat_bones.hpp" | | #include "armadillo_bits/op_symmat_bones.hpp" | |
| #include "armadillo_bits/op_hist_bones.hpp" | | #include "armadillo_bits/op_hist_bones.hpp" | |
| #include "armadillo_bits/op_unique_bones.hpp" | | #include "armadillo_bits/op_unique_bones.hpp" | |
| #include "armadillo_bits/op_toeplitz_bones.hpp" | | #include "armadillo_bits/op_toeplitz_bones.hpp" | |
| #include "armadillo_bits/op_fft_bones.hpp" | | #include "armadillo_bits/op_fft_bones.hpp" | |
| #include "armadillo_bits/op_any_bones.hpp" | | #include "armadillo_bits/op_any_bones.hpp" | |
| #include "armadillo_bits/op_all_bones.hpp" | | #include "armadillo_bits/op_all_bones.hpp" | |
| #include "armadillo_bits/op_normalise_bones.hpp" | | #include "armadillo_bits/op_normalise_bones.hpp" | |
|
| | | #include "armadillo_bits/op_clamp_bones.hpp" | |
| | | | |
| #include "armadillo_bits/glue_times_bones.hpp" | | #include "armadillo_bits/glue_times_bones.hpp" | |
| #include "armadillo_bits/glue_mixed_bones.hpp" | | #include "armadillo_bits/glue_mixed_bones.hpp" | |
| #include "armadillo_bits/glue_cov_bones.hpp" | | #include "armadillo_bits/glue_cov_bones.hpp" | |
| #include "armadillo_bits/glue_cor_bones.hpp" | | #include "armadillo_bits/glue_cor_bones.hpp" | |
| #include "armadillo_bits/glue_kron_bones.hpp" | | #include "armadillo_bits/glue_kron_bones.hpp" | |
| #include "armadillo_bits/glue_cross_bones.hpp" | | #include "armadillo_bits/glue_cross_bones.hpp" | |
| #include "armadillo_bits/glue_join_bones.hpp" | | #include "armadillo_bits/glue_join_bones.hpp" | |
| #include "armadillo_bits/glue_relational_bones.hpp" | | #include "armadillo_bits/glue_relational_bones.hpp" | |
| #include "armadillo_bits/glue_solve_bones.hpp" | | #include "armadillo_bits/glue_solve_bones.hpp" | |
| | | | |
| skipping to change at line 427 | | skipping to change at line 432 | |
| #include "armadillo_bits/fn_fft2.hpp" | | #include "armadillo_bits/fn_fft2.hpp" | |
| #include "armadillo_bits/fn_any.hpp" | | #include "armadillo_bits/fn_any.hpp" | |
| #include "armadillo_bits/fn_all.hpp" | | #include "armadillo_bits/fn_all.hpp" | |
| #include "armadillo_bits/fn_size.hpp" | | #include "armadillo_bits/fn_size.hpp" | |
| #include "armadillo_bits/fn_numel.hpp" | | #include "armadillo_bits/fn_numel.hpp" | |
| #include "armadillo_bits/fn_inplace_strans.hpp" | | #include "armadillo_bits/fn_inplace_strans.hpp" | |
| #include "armadillo_bits/fn_inplace_trans.hpp" | | #include "armadillo_bits/fn_inplace_trans.hpp" | |
| #include "armadillo_bits/fn_randi.hpp" | | #include "armadillo_bits/fn_randi.hpp" | |
| #include "armadillo_bits/fn_cond.hpp" | | #include "armadillo_bits/fn_cond.hpp" | |
| #include "armadillo_bits/fn_normalise.hpp" | | #include "armadillo_bits/fn_normalise.hpp" | |
|
| | | #include "armadillo_bits/fn_clamp.hpp" | |
| | | | |
| #include "armadillo_bits/fn_speye.hpp" | | #include "armadillo_bits/fn_speye.hpp" | |
| #include "armadillo_bits/fn_spones.hpp" | | #include "armadillo_bits/fn_spones.hpp" | |
| #include "armadillo_bits/fn_sprandn.hpp" | | #include "armadillo_bits/fn_sprandn.hpp" | |
| #include "armadillo_bits/fn_sprandu.hpp" | | #include "armadillo_bits/fn_sprandu.hpp" | |
| #include "armadillo_bits/fn_eigs_sym.hpp" | | #include "armadillo_bits/fn_eigs_sym.hpp" | |
| #include "armadillo_bits/fn_eigs_gen.hpp" | | #include "armadillo_bits/fn_eigs_gen.hpp" | |
| #include "armadillo_bits/fn_norm_sparse.hpp" | | #include "armadillo_bits/fn_norm_sparse.hpp" | |
| | | | |
| // | | // | |
| // misc stuff | | // misc stuff | |
| | | | |
| #include "armadillo_bits/hdf5_misc.hpp" | | #include "armadillo_bits/hdf5_misc.hpp" | |
| #include "armadillo_bits/fft_engine.hpp" | | #include "armadillo_bits/fft_engine.hpp" | |
|
| | | #include "armadillo_bits/gmm_misc_bones.hpp" | |
| | | #include "armadillo_bits/gmm_misc_meat.hpp" | |
| | | #include "armadillo_bits/gmm_diag_bones.hpp" | |
| | | #include "armadillo_bits/gmm_diag_meat.hpp" | |
| | | | |
| // | | // | |
| // classes implementing various forms of dense matrix multiplication | | // classes implementing various forms of dense matrix multiplication | |
| | | | |
| #include "armadillo_bits/mul_gemv.hpp" | | #include "armadillo_bits/mul_gemv.hpp" | |
| #include "armadillo_bits/mul_gemm.hpp" | | #include "armadillo_bits/mul_gemm.hpp" | |
| #include "armadillo_bits/mul_gemm_mixed.hpp" | | #include "armadillo_bits/mul_gemm_mixed.hpp" | |
| #include "armadillo_bits/mul_syrk.hpp" | | #include "armadillo_bits/mul_syrk.hpp" | |
| #include "armadillo_bits/mul_herk.hpp" | | #include "armadillo_bits/mul_herk.hpp" | |
| | | | |
| | | | |
| skipping to change at line 536 | | skipping to change at line 546 | |
| #include "armadillo_bits/op_trimat_meat.hpp" | | #include "armadillo_bits/op_trimat_meat.hpp" | |
| #include "armadillo_bits/op_cumsum_meat.hpp" | | #include "armadillo_bits/op_cumsum_meat.hpp" | |
| #include "armadillo_bits/op_symmat_meat.hpp" | | #include "armadillo_bits/op_symmat_meat.hpp" | |
| #include "armadillo_bits/op_hist_meat.hpp" | | #include "armadillo_bits/op_hist_meat.hpp" | |
| #include "armadillo_bits/op_unique_meat.hpp" | | #include "armadillo_bits/op_unique_meat.hpp" | |
| #include "armadillo_bits/op_toeplitz_meat.hpp" | | #include "armadillo_bits/op_toeplitz_meat.hpp" | |
| #include "armadillo_bits/op_fft_meat.hpp" | | #include "armadillo_bits/op_fft_meat.hpp" | |
| #include "armadillo_bits/op_any_meat.hpp" | | #include "armadillo_bits/op_any_meat.hpp" | |
| #include "armadillo_bits/op_all_meat.hpp" | | #include "armadillo_bits/op_all_meat.hpp" | |
| #include "armadillo_bits/op_normalise_meat.hpp" | | #include "armadillo_bits/op_normalise_meat.hpp" | |
|
| | | #include "armadillo_bits/op_clamp_meat.hpp" | |
| | | | |
| #include "armadillo_bits/glue_times_meat.hpp" | | #include "armadillo_bits/glue_times_meat.hpp" | |
| #include "armadillo_bits/glue_mixed_meat.hpp" | | #include "armadillo_bits/glue_mixed_meat.hpp" | |
| #include "armadillo_bits/glue_cov_meat.hpp" | | #include "armadillo_bits/glue_cov_meat.hpp" | |
| #include "armadillo_bits/glue_cor_meat.hpp" | | #include "armadillo_bits/glue_cor_meat.hpp" | |
| #include "armadillo_bits/glue_kron_meat.hpp" | | #include "armadillo_bits/glue_kron_meat.hpp" | |
| #include "armadillo_bits/glue_cross_meat.hpp" | | #include "armadillo_bits/glue_cross_meat.hpp" | |
| #include "armadillo_bits/glue_join_meat.hpp" | | #include "armadillo_bits/glue_join_meat.hpp" | |
| #include "armadillo_bits/glue_relational_meat.hpp" | | #include "armadillo_bits/glue_relational_meat.hpp" | |
| #include "armadillo_bits/glue_solve_meat.hpp" | | #include "armadillo_bits/glue_solve_meat.hpp" | |
| | | | |
End of changes. 5 change blocks. |
| 0 lines changed or deleted | | 11 lines changed or added | |
|
| spop_max_meat.hpp | | spop_max_meat.hpp | |
|
| // Copyright (C) 2012 Ryan Curtin | | // Copyright (C) 2012-2014 Ryan Curtin | |
| // Copyright (C) 2012 Conrad Sanderson | | // Copyright (C) 2012-2014 Conrad Sanderson | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup spop_max | | //! \addtogroup spop_max | |
| //! @{ | | //! @{ | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| | | | |
| skipping to change at line 60 | | skipping to change at line 60 | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | | |
| if(dim == 0) | | if(dim == 0) | |
| { | | { | |
| // maximum in each column | | // maximum in each column | |
| result.set_size(1, p.get_n_cols()); | | result.set_size(1, p.get_n_cols()); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
|
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
|
| uword cur_col = it.col(); | | uword cur_col = it.col(); | |
| uword elem_in_col = 1; | | uword elem_in_col = 1; | |
|
| | | | |
| eT cur_max = (*it); | | eT cur_max = (*it); | |
| ++it; | | ++it; | |
| | | | |
|
| while(it != p.end()) | | while(it != it_end) | |
| { | | { | |
| if(it.col() != cur_col) | | if(it.col() != cur_col) | |
| { | | { | |
| // was the column full? | | // was the column full? | |
| if(elem_in_col == p.get_n_rows()) | | if(elem_in_col == p.get_n_rows()) | |
| { | | { | |
| result.at(0, cur_col) = cur_max; | | result.at(0, cur_col) = cur_max; | |
| } | | } | |
| else | | else | |
| { | | { | |
| result.at(0, cur_col) = std::max(eT(0), cur_max); | | result.at(0, cur_col) = std::max(eT(0), cur_max); | |
| } | | } | |
| | | | |
|
| cur_col = it.col(); | | cur_col = it.col(); | |
| elem_in_col = 0; | | elem_in_col = 0; | |
|
| | | | |
| cur_max = (*it); | | cur_max = (*it); | |
| } | | } | |
| else | | else | |
| { | | { | |
| cur_max = std::max(cur_max, *it); | | cur_max = std::max(cur_max, *it); | |
| } | | } | |
| | | | |
| ++elem_in_col; | | ++elem_in_col; | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| skipping to change at line 113 | | skipping to change at line 113 | |
| else | | else | |
| { | | { | |
| result.at(0, cur_col) = std::max(eT(0), cur_max); | | result.at(0, cur_col) = std::max(eT(0), cur_max); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // maximum in each row | | // maximum in each row | |
| result.set_size(p.get_n_rows(), 1); | | result.set_size(p.get_n_rows(), 1); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
| typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | | typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | |
| | | | |
|
| uword cur_row = it.row(); | | uword cur_row = it.row(); | |
| uword elem_in_row = 1; | | uword elem_in_row = 1; | |
|
| | | | |
| eT cur_max = (*it); | | eT cur_max = (*it); | |
| ++it; | | ++it; | |
| | | | |
| while(it.pos() < p.get_n_nonzero()) | | while(it.pos() < p.get_n_nonzero()) | |
| { | | { | |
| if(it.row() != cur_row) | | if(it.row() != cur_row) | |
| { | | { | |
| // was the row full? | | // was the row full? | |
| if(elem_in_row == p.get_n_cols()) | | if(elem_in_row == p.get_n_cols()) | |
| { | | { | |
| result.at(cur_row, 0) = cur_max; | | result.at(cur_row, 0) = cur_max; | |
| } | | } | |
| else | | else | |
| { | | { | |
| result.at(cur_row, 0) = std::max(eT(0), cur_max); | | result.at(cur_row, 0) = std::max(eT(0), cur_max); | |
| } | | } | |
| | | | |
|
| cur_row = it.row(); | | cur_row = it.row(); | |
| elem_in_row = 0; | | elem_in_row = 0; | |
|
| | | | |
| cur_max = (*it); | | cur_max = (*it); | |
| } | | } | |
| else | | else | |
| { | | { | |
| cur_max = std::max(cur_max, *it); | | cur_max = std::max(cur_max, *it); | |
| } | | } | |
| | | | |
| ++elem_in_row; | | ++elem_in_row; | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| skipping to change at line 165 | | skipping to change at line 164 | |
| } | | } | |
| else | | else | |
| { | | { | |
| result.at(cur_row, 0) = std::max(eT(0), cur_max); | | result.at(cur_row, 0) = std::max(eT(0), cur_max); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
|
| | | typename T1::elem_type | |
| | | spop_max::vector_max | |
| | | ( | |
| | | const T1& x, | |
| | | const typename arma_not_cx<typename T1::elem_type>::result* junk | |
| | | ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | arma_ignore(junk); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | | |
| | | const SpProxy<T1> p(x); | |
| | | | |
| | | if(p.get_n_nonzero() == 0) { return eT(0); } | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == false) | |
| | | { | |
| | | // direct access of values | |
| | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| | | { | |
| | | return op_max::direct_max(p.get_values(), p.get_n_nonzero()); | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::max(eT(0), op_max::direct_max(p.get_values(), p.get_n_non | |
| | | zero())); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | // use iterator | |
| | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
| | | eT result = (*it); | |
| | | ++it; | |
| | | | |
| | | while(it != it_end) | |
| | | { | |
| | | if((*it) > result) { result = (*it); } | |
| | | | |
| | | ++it; | |
| | | } | |
| | | | |
| | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| | | { | |
| | | return result; | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::max(eT(0), result); | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| | | typename arma_not_cx<typename T1::elem_type>::result | |
| | | spop_max::max(const SpBase<typename T1::elem_type, T1>& X) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | | |
| | | const SpProxy<T1> P(X.get_ref()); | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | const uword n_nonzero = P.get_n_nonzero(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "max(): given object has no elements"); | |
| | | | |
| | | eT max_val = priv::most_neg<eT>(); | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == true) | |
| | | { | |
| | | // We have to iterate over the elements. | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | if ((*it) > max_val) { max_val = *it; } | |
| | | | |
| | | ++it; | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | // We can do direct access of the values, row_indices, and col_ptrs. | |
| | | // We don't need the location of the max value, so we can just call out | |
| | | to | |
| | | // other functions... | |
| | | max_val = op_max::direct_max(P.get_values(), n_nonzero); | |
| | | } | |
| | | | |
| | | if(n_elem == n_nonzero) | |
| | | { | |
| | | return max_val; | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::max(eT(0), max_val); | |
| | | } | |
| | | } | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| | | typename arma_not_cx<typename T1::elem_type>::result | |
| | | spop_max::max_with_index(const SpProxy<T1>& P, uword& index_of_max_val) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | const uword n_nonzero = P.get_n_nonzero(); | |
| | | const uword n_rows = P.get_n_rows(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "max(): given object has no elements"); | |
| | | | |
| | | eT max_val = priv::most_neg<eT>(); | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == true) | |
| | | { | |
| | | // We have to iterate over the elements. | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | if ((*it) > max_val) | |
| | | { | |
| | | max_val = *it; | |
| | | index_of_max_val = it.row() + it.col() * n_rows; | |
| | | } | |
| | | | |
| | | ++it; | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | // We can do direct access. | |
| | | max_val = op_max::direct_max(P.get_values(), n_nonzero, index_of_max_va | |
| | | l); | |
| | | | |
| | | // Convert to actual position in matrix. | |
| | | const uword row = P.get_row_indices()[index_of_max_val]; | |
| | | uword col = 0; | |
| | | while (P.get_col_ptrs()[++col] <= index_of_max_val) { } | |
| | | index_of_max_val = (col - 1) * n_rows + row; | |
| | | } | |
| | | | |
| | | if(n_elem != n_nonzero) | |
| | | { | |
| | | max_val = std::max(eT(0), max_val); | |
| | | | |
| | | // If the max_val is a nonzero element, we need its actual position in | |
| | | the matrix. | |
| | | if(max_val == eT(0)) | |
| | | { | |
| | | // Find first zero element. | |
| | | uword last_row = 0; | |
| | | uword last_col = 0; | |
| | | | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | // Have we moved more than one position from the last place? | |
| | | if ((it.col() == last_col) && (it.row() - last_row > 1)) | |
| | | { | |
| | | index_of_max_val = it.col() * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) | |
| | | { | |
| | | index_of_max_val = last_col * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() == last_col + 1) && (it.row() > 0)) | |
| | | { | |
| | | index_of_max_val = it.col() * n_rows; | |
| | | break; | |
| | | } | |
| | | else if (it.col() > last_col + 1) | |
| | | { | |
| | | index_of_max_val = (last_col + 1) * n_rows; | |
| | | break; | |
| | | } | |
| | | | |
| | | last_row = it.row(); | |
| | | last_col = it.col(); | |
| | | ++it; | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | return max_val; | |
| | | } | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| void | | void | |
| spop_max::apply_noalias | | spop_max::apply_noalias | |
| ( | | ( | |
| SpMat<typename T1::elem_type>& result, | | SpMat<typename T1::elem_type>& result, | |
| const SpProxy<T1>& p, | | const SpProxy<T1>& p, | |
| const uword dim, | | const uword dim, | |
| const typename arma_cx_only<typename T1::elem_type>::result* junk | | const typename arma_cx_only<typename T1::elem_type>::result* junk | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| typedef typename get_pod_type<eT>::result T; | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
| if(dim == 0) | | if(dim == 0) | |
| { | | { | |
| // maximum in each column | | // maximum in each column | |
| result.set_size(1, p.get_n_cols()); | | result.set_size(1, p.get_n_cols()); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
|
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
|
| uword cur_col = it.col(); | | uword cur_col = it.col(); | |
| uword elem_in_col = 1; | | uword elem_in_col = 1; | |
| | | | |
| eT cur_max_orig = *it; | | eT cur_max_orig = *it; | |
| T cur_max_abs = std::abs(cur_max_orig); | | T cur_max_abs = std::abs(cur_max_orig); | |
| | | | |
| ++it; | | ++it; | |
| | | | |
|
| while(it != p.end()) | | while(it != it_end) | |
| { | | { | |
| if(it.col() != cur_col) | | if(it.col() != cur_col) | |
| { | | { | |
| // was the column full? | | // was the column full? | |
| if(elem_in_col == p.get_n_rows()) | | if(elem_in_col == p.get_n_rows()) | |
| { | | { | |
| result.at(0, cur_col) = cur_max_orig; | | result.at(0, cur_col) = cur_max_orig; | |
| } | | } | |
| else | | else | |
| { | | { | |
| eT val1 = eT(0); | | eT val1 = eT(0); | |
| | | | |
| result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1
: cur_max_orig; | | result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1
: cur_max_orig; | |
| } | | } | |
| | | | |
|
| cur_col = it.col(); | | cur_col = it.col(); | |
| elem_in_col = 0; | | elem_in_col = 0; | |
| | | | |
| cur_max_orig = *it; | | cur_max_orig = *it; | |
| cur_max_abs = std::abs(cur_max_orig); | | cur_max_abs = std::abs(cur_max_orig); | |
| } | | } | |
| else | | else | |
| { | | { | |
| eT val1_orig = *it; | | eT val1_orig = *it; | |
| T val1_abs = std::abs(val1_orig); | | T val1_abs = std::abs(val1_orig); | |
| | | | |
| | | | |
| skipping to change at line 254 | | skipping to change at line 457 | |
| eT val1 = eT(0); | | eT val1 = eT(0); | |
| | | | |
| result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cu
r_max_orig; | | result.at(0, cur_col) = ( std::abs(val1) >= cur_max_abs ) ? val1 : cu
r_max_orig; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // maximum in each row | | // maximum in each row | |
| result.set_size(p.get_n_rows(), 1); | | result.set_size(p.get_n_rows(), 1); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
| typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | | typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | |
| | | | |
|
| uword cur_row = it.row(); | | uword cur_row = it.row(); | |
| uword elem_in_row = 1; | | uword elem_in_row = 1; | |
| | | | |
| eT cur_max_orig = *it; | | eT cur_max_orig = *it; | |
| T cur_max_abs = std::abs(cur_max_orig); | | T cur_max_abs = std::abs(cur_max_orig); | |
| | | | |
| ++it; | | ++it; | |
| | | | |
| while(it.pos() < p.get_n_nonzero()) | | while(it.pos() < p.get_n_nonzero()) | |
| { | | { | |
| if(it.row() != cur_row) | | if(it.row() != cur_row) | |
| | | | |
| skipping to change at line 326 | | skipping to change at line 526 | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| typename T1::elem_type | | typename T1::elem_type | |
| spop_max::vector_max | | spop_max::vector_max | |
| ( | | ( | |
| const T1& x, | | const T1& x, | |
|
| const typename arma_not_cx<typename T1::elem_type>::result* junk | | const typename arma_cx_only<typename T1::elem_type>::result* junk | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
|
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
| const SpProxy<T1> p(x); | | const SpProxy<T1> p(x); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return eT(0); } | |
| { | | | |
| return eT(0); | | | |
| } | | | |
| | | | |
| if(SpProxy<T1>::must_use_iterator == false) | | if(SpProxy<T1>::must_use_iterator == false) | |
| { | | { | |
| // direct access of values | | // direct access of values | |
| if(p.get_n_nonzero() == p.get_n_elem()) | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| { | | { | |
| return op_max::direct_max(p.get_values(), p.get_n_nonzero()); | | return op_max::direct_max(p.get_values(), p.get_n_nonzero()); | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| return std::max(eT(0), op_max::direct_max(p.get_values(), p.get_n_non | | const eT val1 = eT(0); | |
| zero())); | | const eT val2 = op_max::direct_max(p.get_values(), p.get_n_nonzero()) | |
| | | ; | |
| | | | |
| | | return ( std::abs(val1) >= std::abs(val2) ) ? val1 : val2; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // use iterator | | // use iterator | |
|
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
| | | eT best_val_orig = *it; | |
| | | T best_val_abs = std::abs(best_val_orig); | |
| | | | |
|
| eT result = (*it); | | | |
| ++it; | | ++it; | |
| | | | |
|
| while(it != p.end()) | | while(it != it_end) | |
| { | | { | |
|
| if((*it) > result) | | eT val_orig = *it; | |
| | | T val_abs = std::abs(val_orig); | |
| | | | |
| | | if(val_abs > best_val_abs) | |
| { | | { | |
|
| result = (*it); | | best_val_abs = val_abs; | |
| | | best_val_orig = val_orig; | |
| } | | } | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| if(p.get_n_nonzero() == p.get_n_elem()) | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| { | | { | |
|
| return result; | | return best_val_orig; | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| return std::max(eT(0), result); | | const eT val1 = eT(0); | |
| | | | |
| | | return ( std::abs(val1) >= best_val_abs ) ? val1 : best_val_orig; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
|
| typename T1::elem_type | | typename arma_cx_only<typename T1::elem_type>::result | |
| spop_max::vector_max | | spop_max::max(const SpBase<typename T1::elem_type, T1>& X) | |
| ( | | | |
| const T1& x, | | | |
| const typename arma_cx_only<typename T1::elem_type>::result* junk | | | |
| ) | | | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
|
| arma_ignore(junk); | | | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| typedef typename get_pod_type<eT>::result T; | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
|
| const SpProxy<T1> p(x); | | const SpProxy<T1> P(X.get_ref()); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | const uword n_elem = P.get_n_elem(); | |
| { | | const uword n_nonzero = P.get_n_nonzero(); | |
| return eT(0); | | | |
| } | | | |
| | | | |
|
| if(SpProxy<T1>::must_use_iterator == false) | | arma_debug_check( (n_elem == 0), "max(): given object has no elements"); | |
| | | | |
| | | T max_val = priv::most_neg<T>(); | |
| | | eT ret_val; | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == true) | |
| { | | { | |
|
| // direct access of values | | // We have to iterate over the elements. | |
| if(p.get_n_nonzero() == p.get_n_elem()) | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| { | | | |
| return op_max::direct_max(p.get_values(), p.get_n_nonzero()); | | it_type it = P.begin(); | |
| } | | it_type it_end = P.end(); | |
| else | | | |
| | | while (it != it_end) | |
| { | | { | |
|
| const eT val1 = eT(0); | | const T tmp_val = std::abs(*it); | |
| const eT val2 = op_max::direct_max(p.get_values(), p.get_n_nonzero()) | | | |
| ; | | | |
| | | | |
|
| return ( std::abs(val1) >= std::abs(val2) ) ? val1 : val2; | | if (tmp_val > max_val) | |
| | | { | |
| | | max_val = tmp_val; | |
| | | ret_val = *it; | |
| | | } | |
| | | | |
| | | ++it; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| // use iterator | | // We can do direct access of the values, row_indices, and col_ptrs. | |
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | // We don't need the location of the max value, so we can just call out | |
| | | to | |
| | | // other functions... | |
| | | ret_val = op_max::direct_max(P.get_values(), n_nonzero); | |
| | | max_val = std::abs(ret_val); | |
| | | } | |
| | | | |
|
| eT best_val_orig = *it; | | if(n_elem == n_nonzero) | |
| T best_val_abs = std::abs(best_val_orig); | | { | |
| | | return max_val; | |
| | | } | |
| | | else | |
| | | { | |
| | | if (T(0) > max_val) | |
| | | return eT(0); | |
| | | else | |
| | | return ret_val; | |
| | | } | |
| | | } | |
| | | | |
|
| ++it; | | template<typename T1> | |
| | | inline | |
| | | typename arma_cx_only<typename T1::elem_type>::result | |
| | | spop_max::max_with_index(const SpProxy<T1>& P, uword& index_of_max_val) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | const uword n_nonzero = P.get_n_nonzero(); | |
| | | const uword n_rows = P.get_n_rows(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "max(): given object has no elements"); | |
| | | | |
| | | T max_val = priv::most_neg<T>(); | |
| | | | |
|
| while(it != p.end()) | | if(SpProxy<T1>::must_use_iterator == true) | |
| | | { | |
| | | // We have to iterate over the elements. | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| { | | { | |
|
| eT val_orig = *it; | | const T tmp_val = std::abs(*it); | |
| T val_abs = std::abs(val_orig); | | | |
| | | | |
|
| if(val_abs > best_val_abs) | | if (tmp_val > max_val) | |
| { | | { | |
|
| best_val_abs = val_abs; | | max_val = tmp_val; | |
| best_val_orig = val_orig; | | index_of_max_val = it.row() + it.col() * n_rows; | |
| } | | } | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
|
| | | } | |
| | | else | |
| | | { | |
| | | // We can do direct access. | |
| | | max_val = std::abs(op_max::direct_max(P.get_values(), n_nonzero, index_ | |
| | | of_max_val)); | |
| | | | |
|
| if(p.get_n_nonzero() == p.get_n_elem()) | | // Convert to actual position in matrix. | |
| { | | const uword row = P.get_row_indices()[index_of_max_val]; | |
| return best_val_orig; | | uword col = 0; | |
| } | | while (P.get_col_ptrs()[++col] <= index_of_max_val) { } | |
| else | | index_of_max_val = (col - 1) * n_rows + row; | |
| | | } | |
| | | | |
| | | if(n_elem != n_nonzero) | |
| | | { | |
| | | max_val = std::max(T(0), max_val); | |
| | | | |
| | | // If the max_val is a nonzero element, we need its actual position in | |
| | | the matrix. | |
| | | if(max_val == T(0)) | |
| { | | { | |
|
| const eT val1 = eT(0); | | // Find first zero element. | |
| | | uword last_row = 0; | |
| | | uword last_col = 0; | |
| | | | |
|
| return ( std::abs(val1) >= best_val_abs ) ? val1 : best_val_orig; | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | // Have we moved more than one position from the last place? | |
| | | if ((it.col() == last_col) && (it.row() - last_row > 1)) | |
| | | { | |
| | | index_of_max_val = it.col() * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) | |
| | | { | |
| | | index_of_max_val = last_col * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() == last_col + 1) && (it.row() > 0)) | |
| | | { | |
| | | index_of_max_val = it.col() * n_rows; | |
| | | break; | |
| | | } | |
| | | else if (it.col() > last_col + 1) | |
| | | { | |
| | | index_of_max_val = (last_col + 1) * n_rows; | |
| | | break; | |
| | | } | |
| | | | |
| | | last_row = it.row(); | |
| | | last_col = it.col(); | |
| | | ++it; | |
| | | } | |
| } | | } | |
| } | | } | |
|
| | | | |
| | | return P[index_of_max_val]; | |
| } | | } | |
| | | | |
| //! @} | | //! @} | |
| | | | |
End of changes. 52 change blocks. |
| 85 lines changed or deleted | | 391 lines changed or added | |
|
| spop_min_meat.hpp | | spop_min_meat.hpp | |
|
| // Copyright (C) 2012 Ryan Curtin | | // Copyright (C) 2012-2014 Ryan Curtin | |
| // Copyright (C) 2012 Conrad Sanderson | | // Copyright (C) 2012-2014 Conrad Sanderson | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup spop_min | | //! \addtogroup spop_min | |
| //! @{ | | //! @{ | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| | | | |
| skipping to change at line 60 | | skipping to change at line 60 | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | | |
| if(dim == 0) | | if(dim == 0) | |
| { | | { | |
| // minimum in each column | | // minimum in each column | |
| result.set_size(1, p.get_n_cols()); | | result.set_size(1, p.get_n_cols()); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
|
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
|
| uword cur_col = it.col(); | | uword cur_col = it.col(); | |
| uword elem_in_col = 1; | | uword elem_in_col = 1; | |
|
| | | | |
| eT cur_min = (*it); | | eT cur_min = (*it); | |
| ++it; | | ++it; | |
| | | | |
|
| while(it != p.end()) | | while(it != it_end) | |
| { | | { | |
| if(it.col() != cur_col) | | if(it.col() != cur_col) | |
| { | | { | |
| // was the column full? | | // was the column full? | |
| if(elem_in_col == p.get_n_rows()) | | if(elem_in_col == p.get_n_rows()) | |
| { | | { | |
| result.at(0, cur_col) = cur_min; | | result.at(0, cur_col) = cur_min; | |
| } | | } | |
| else | | else | |
| { | | { | |
| result.at(0, cur_col) = std::min(eT(0), cur_min); | | result.at(0, cur_col) = std::min(eT(0), cur_min); | |
| } | | } | |
| | | | |
|
| cur_col = it.col(); | | cur_col = it.col(); | |
| elem_in_col = 0; | | elem_in_col = 0; | |
|
| | | | |
| cur_min = (*it); | | cur_min = (*it); | |
| } | | } | |
| else | | else | |
| { | | { | |
| cur_min = std::min(cur_min, *it); | | cur_min = std::min(cur_min, *it); | |
| } | | } | |
| | | | |
| ++elem_in_col; | | ++elem_in_col; | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| skipping to change at line 113 | | skipping to change at line 113 | |
| else | | else | |
| { | | { | |
| result.at(0, cur_col) = std::min(eT(0), cur_min); | | result.at(0, cur_col) = std::min(eT(0), cur_min); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // minimum in each row | | // minimum in each row | |
| result.set_size(p.get_n_rows(), 1); | | result.set_size(p.get_n_rows(), 1); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
| typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | | typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | |
| | | | |
|
| uword cur_row = it.row(); | | uword cur_row = it.row(); | |
| uword elem_in_row = 1; | | uword elem_in_row = 1; | |
|
| | | | |
| eT cur_min = (*it); | | eT cur_min = (*it); | |
| ++it; | | ++it; | |
| | | | |
| while(it.pos() < p.get_n_nonzero()) | | while(it.pos() < p.get_n_nonzero()) | |
| { | | { | |
| if(it.row() != cur_row) | | if(it.row() != cur_row) | |
| { | | { | |
| // was the row full? | | // was the row full? | |
| if(elem_in_row == p.get_n_cols()) | | if(elem_in_row == p.get_n_cols()) | |
| { | | { | |
| result.at(cur_row, 0) = cur_min; | | result.at(cur_row, 0) = cur_min; | |
| } | | } | |
| else | | else | |
| { | | { | |
| result.at(cur_row, 0) = std::min(eT(0), cur_min); | | result.at(cur_row, 0) = std::min(eT(0), cur_min); | |
| } | | } | |
| | | | |
|
| cur_row = it.row(); | | cur_row = it.row(); | |
| elem_in_row = 0; | | elem_in_row = 0; | |
|
| | | | |
| cur_min = (*it); | | cur_min = (*it); | |
| } | | } | |
| else | | else | |
| { | | { | |
| cur_min = std::min(cur_min, *it); | | cur_min = std::min(cur_min, *it); | |
| } | | } | |
| | | | |
| ++elem_in_row; | | ++elem_in_row; | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| skipping to change at line 165 | | skipping to change at line 164 | |
| } | | } | |
| else | | else | |
| { | | { | |
| result.at(cur_row, 0) = std::min(eT(0), cur_min); | | result.at(cur_row, 0) = std::min(eT(0), cur_min); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
|
| | | typename T1::elem_type | |
| | | spop_min::vector_min | |
| | | ( | |
| | | const T1& x, | |
| | | const typename arma_not_cx<typename T1::elem_type>::result* junk | |
| | | ) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | arma_ignore(junk); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | | |
| | | const SpProxy<T1> p(x); | |
| | | | |
| | | if(p.get_n_nonzero() == 0) { return eT(0); } | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == false) | |
| | | { | |
| | | // direct access of values | |
| | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| | | { | |
| | | return op_min::direct_min(p.get_values(), p.get_n_nonzero()); | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::min(eT(0), op_min::direct_min(p.get_values(), p.get_n_non | |
| | | zero())); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | // use iterator | |
| | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
| | | eT result = (*it); | |
| | | ++it; | |
| | | | |
| | | while(it != it_end) | |
| | | { | |
| | | if((*it) < result) { result = (*it); } | |
| | | | |
| | | ++it; | |
| | | } | |
| | | | |
| | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| | | { | |
| | | return result; | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::min(eT(0), result); | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| | | typename arma_not_cx<typename T1::elem_type>::result | |
| | | spop_min::min(const SpBase<typename T1::elem_type, T1>& X) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | | |
| | | const SpProxy<T1> P(X.get_ref()); | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | const uword n_nonzero = P.get_n_nonzero(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "min(): given object has no elements"); | |
| | | | |
| | | eT min_val = priv::most_pos<eT>(); | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == true) | |
| | | { | |
| | | // We have to iterate over the elements. | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | if ((*it) < min_val) { min_val = *it; } | |
| | | | |
| | | ++it; | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | // We can do direct access of the values, row_indices, and col_ptrs. | |
| | | // We don't need the location of the min value, so we can just call out | |
| | | to | |
| | | // other functions... | |
| | | min_val = op_min::direct_min(P.get_values(), n_nonzero); | |
| | | } | |
| | | | |
| | | if(n_elem == n_nonzero) | |
| | | { | |
| | | return min_val; | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::min(eT(0), min_val); | |
| | | } | |
| | | } | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| | | typename arma_not_cx<typename T1::elem_type>::result | |
| | | spop_min::min_with_index(const SpProxy<T1>& P, uword& index_of_min_val) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | const uword n_nonzero = P.get_n_nonzero(); | |
| | | const uword n_rows = P.get_n_rows(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "min(): given object has no elements"); | |
| | | | |
| | | eT min_val = priv::most_pos<eT>(); | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == true) | |
| | | { | |
| | | // We have to iterate over the elements. | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | if ((*it) < min_val) | |
| | | { | |
| | | min_val = *it; | |
| | | index_of_min_val = it.row() + it.col() * n_rows; | |
| | | } | |
| | | | |
| | | ++it; | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | // We can do direct access. | |
| | | min_val = op_min::direct_min(P.get_values(), n_nonzero, index_of_min_va | |
| | | l); | |
| | | | |
| | | // Convert to actual position in matrix. | |
| | | const uword row = P.get_row_indices()[index_of_min_val]; | |
| | | uword col = 0; | |
| | | while (P.get_col_ptrs()[++col] < index_of_min_val + 1) { } | |
| | | index_of_min_val = (col - 1) * n_rows + row; | |
| | | } | |
| | | | |
| | | if(n_elem != n_nonzero) | |
| | | { | |
| | | min_val = std::min(eT(0), min_val); | |
| | | | |
| | | // If the min_val is a nonzero element, we need its actual position in | |
| | | the matrix. | |
| | | if(min_val == eT(0)) | |
| | | { | |
| | | // Find first zero element. | |
| | | uword last_row = 0; | |
| | | uword last_col = 0; | |
| | | | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | // Have we moved more than one position from the last place? | |
| | | if ((it.col() == last_col) && (it.row() - last_row > 1)) | |
| | | { | |
| | | index_of_min_val = it.col() * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) | |
| | | { | |
| | | index_of_min_val = last_col * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() == last_col + 1) && (it.row() > 0)) | |
| | | { | |
| | | index_of_min_val = it.col() * n_rows; | |
| | | break; | |
| | | } | |
| | | else if (it.col() > last_col + 1) | |
| | | { | |
| | | index_of_min_val = (last_col + 1) * n_rows; | |
| | | break; | |
| | | } | |
| | | | |
| | | last_row = it.row(); | |
| | | last_col = it.col(); | |
| | | ++it; | |
| | | } | |
| | | } | |
| | | } | |
| | | | |
| | | return min_val; | |
| | | } | |
| | | | |
| | | template<typename T1> | |
| | | inline | |
| void | | void | |
| spop_min::apply_noalias | | spop_min::apply_noalias | |
| ( | | ( | |
| SpMat<typename T1::elem_type>& result, | | SpMat<typename T1::elem_type>& result, | |
| const SpProxy<T1>& p, | | const SpProxy<T1>& p, | |
| const uword dim, | | const uword dim, | |
| const typename arma_cx_only<typename T1::elem_type>::result* junk | | const typename arma_cx_only<typename T1::elem_type>::result* junk | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| typedef typename get_pod_type<eT>::result T; | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
| if(dim == 0) | | if(dim == 0) | |
| { | | { | |
| // minimum in each column | | // minimum in each column | |
| result.set_size(1, p.get_n_cols()); | | result.set_size(1, p.get_n_cols()); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
|
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
|
| uword cur_col = it.col(); | | uword cur_col = it.col(); | |
| uword elem_in_col = 1; | | uword elem_in_col = 1; | |
| | | | |
| eT cur_min_orig = *it; | | eT cur_min_orig = *it; | |
| T cur_min_abs = std::abs(cur_min_orig); | | T cur_min_abs = std::abs(cur_min_orig); | |
| | | | |
| ++it; | | ++it; | |
| | | | |
|
| while(it != p.end()) | | while(it != it_end) | |
| { | | { | |
| if(it.col() != cur_col) | | if(it.col() != cur_col) | |
| { | | { | |
| // was the column full? | | // was the column full? | |
| if(elem_in_col == p.get_n_rows()) | | if(elem_in_col == p.get_n_rows()) | |
| { | | { | |
| result.at(0, cur_col) = cur_min_orig; | | result.at(0, cur_col) = cur_min_orig; | |
| } | | } | |
| else | | else | |
| { | | { | |
| eT val1 = eT(0); | | eT val1 = eT(0); | |
| | | | |
| result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 :
cur_min_orig; | | result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 :
cur_min_orig; | |
| } | | } | |
| | | | |
|
| cur_col = it.col(); | | cur_col = it.col(); | |
| elem_in_col = 0; | | elem_in_col = 0; | |
| | | | |
| cur_min_orig = *it; | | cur_min_orig = *it; | |
| cur_min_abs = std::abs(cur_min_orig); | | cur_min_abs = std::abs(cur_min_orig); | |
| } | | } | |
| else | | else | |
| { | | { | |
| eT val1_orig = *it; | | eT val1_orig = *it; | |
| T val1_abs = std::abs(val1_orig); | | T val1_abs = std::abs(val1_orig); | |
| | | | |
| | | | |
| skipping to change at line 254 | | skipping to change at line 457 | |
| eT val1 = eT(0); | | eT val1 = eT(0); | |
| | | | |
| result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur
_min_orig; | | result.at(0, cur_col) = ( std::abs(val1) < cur_min_abs ) ? val1 : cur
_min_orig; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // minimum in each row | | // minimum in each row | |
| result.set_size(p.get_n_rows(), 1); | | result.set_size(p.get_n_rows(), 1); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return; } | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
| typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | | typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(); | |
| | | | |
|
| uword cur_row = it.row(); | | uword cur_row = it.row(); | |
| uword elem_in_row = 1; | | uword elem_in_row = 1; | |
| | | | |
| eT cur_min_orig = *it; | | eT cur_min_orig = *it; | |
| T cur_min_abs = std::abs(cur_min_orig); | | T cur_min_abs = std::abs(cur_min_orig); | |
| | | | |
| ++it; | | ++it; | |
| | | | |
| while(it.pos() < p.get_n_nonzero()) | | while(it.pos() < p.get_n_nonzero()) | |
| { | | { | |
| if(it.row() != cur_row) | | if(it.row() != cur_row) | |
| | | | |
| skipping to change at line 326 | | skipping to change at line 526 | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| typename T1::elem_type | | typename T1::elem_type | |
| spop_min::vector_min | | spop_min::vector_min | |
| ( | | ( | |
| const T1& x, | | const T1& x, | |
|
| const typename arma_not_cx<typename T1::elem_type>::result* junk | | const typename arma_cx_only<typename T1::elem_type>::result* junk | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
|
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
| const SpProxy<T1> p(x); | | const SpProxy<T1> p(x); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | if(p.get_n_nonzero() == 0) { return eT(0); } | |
| { | | | |
| return eT(0); | | | |
| } | | | |
| | | | |
| if(SpProxy<T1>::must_use_iterator == false) | | if(SpProxy<T1>::must_use_iterator == false) | |
| { | | { | |
| // direct access of values | | // direct access of values | |
| if(p.get_n_nonzero() == p.get_n_elem()) | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| { | | { | |
| return op_min::direct_min(p.get_values(), p.get_n_nonzero()); | | return op_min::direct_min(p.get_values(), p.get_n_nonzero()); | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| return std::min(eT(0), op_min::direct_min(p.get_values(), p.get_n_non | | const eT val1 = eT(0); | |
| zero())); | | const eT val2 = op_min::direct_min(p.get_values(), p.get_n_nonzero()) | |
| | | ; | |
| | | | |
| | | return ( std::abs(val1) < std::abs(val2) ) ? val1 : val2; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| // use iterator | | // use iterator | |
|
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | typename SpProxy<T1>::const_iterator_type it = p.begin(); | |
| | | typename SpProxy<T1>::const_iterator_type it_end = p.end(); | |
| | | | |
| | | eT best_val_orig = *it; | |
| | | T best_val_abs = std::abs(best_val_orig); | |
| | | | |
|
| eT result = (*it); | | | |
| ++it; | | ++it; | |
| | | | |
|
| while(it != p.end()) | | while(it != it_end) | |
| { | | { | |
|
| if((*it) < result) | | eT val_orig = *it; | |
| | | T val_abs = std::abs(val_orig); | |
| | | | |
| | | if(val_abs < best_val_abs) | |
| { | | { | |
|
| result = (*it); | | best_val_abs = val_abs; | |
| | | best_val_orig = val_orig; | |
| } | | } | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
| | | | |
| if(p.get_n_nonzero() == p.get_n_elem()) | | if(p.get_n_nonzero() == p.get_n_elem()) | |
| { | | { | |
|
| return result; | | return best_val_orig; | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| return std::min(eT(0), result); | | const eT val1 = eT(0); | |
| | | | |
| | | return ( std::abs(val1) < best_val_abs ) ? val1 : best_val_orig; | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
|
| typename T1::elem_type | | typename arma_cx_only<typename T1::elem_type>::result | |
| spop_min::vector_min | | spop_min::min(const SpBase<typename T1::elem_type, T1>& X) | |
| ( | | | |
| const T1& x, | | | |
| const typename arma_cx_only<typename T1::elem_type>::result* junk | | | |
| ) | | | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
|
| arma_ignore(junk); | | | |
| | | | |
| typedef typename T1::elem_type eT; | | typedef typename T1::elem_type eT; | |
| typedef typename get_pod_type<eT>::result T; | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
|
| const SpProxy<T1> p(x); | | const SpProxy<T1> P(X.get_ref()); | |
| | | | |
|
| if(p.get_n_nonzero() == 0) | | const uword n_elem = P.get_n_elem(); | |
| { | | const uword n_nonzero = P.get_n_nonzero(); | |
| return eT(0); | | | |
| } | | | |
| | | | |
|
| if(SpProxy<T1>::must_use_iterator == false) | | arma_debug_check( (n_elem == 0), "min(): given object has no elements"); | |
| | | | |
| | | T min_val = priv::most_pos<T>(); | |
| | | eT ret_val; | |
| | | | |
| | | if(SpProxy<T1>::must_use_iterator == true) | |
| { | | { | |
|
| // direct access of values | | // We have to iterate over the elements. | |
| if(p.get_n_nonzero() == p.get_n_elem()) | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| { | | | |
| return op_min::direct_min(p.get_values(), p.get_n_nonzero()); | | it_type it = P.begin(); | |
| } | | it_type it_end = P.end(); | |
| else | | | |
| | | while (it != it_end) | |
| { | | { | |
|
| const eT val1 = eT(0); | | const T tmp_val = std::abs(*it); | |
| const eT val2 = op_min::direct_min(p.get_values(), p.get_n_nonzero()) | | | |
| ; | | | |
| | | | |
|
| return ( std::abs(val1) < std::abs(val2) ) ? val1 : val2; | | if (tmp_val < min_val) | |
| | | { | |
| | | min_val = tmp_val; | |
| | | ret_val = *it; | |
| | | } | |
| | | | |
| | | ++it; | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| // use iterator | | // We can do direct access of the values, row_indices, and col_ptrs. | |
| typename SpProxy<T1>::const_iterator_type it = p.begin(); | | // We don't need the location of the min value, so we can just call out | |
| | | to | |
| | | // other functions... | |
| | | ret_val = op_min::direct_min(P.get_values(), n_nonzero); | |
| | | min_val = std::abs(ret_val); | |
| | | } | |
| | | | |
|
| eT best_val_orig = *it; | | if(n_elem == n_nonzero) | |
| T best_val_abs = std::abs(best_val_orig); | | { | |
| | | return ret_val; | |
| | | } | |
| | | else | |
| | | { | |
| | | if (T(0) < min_val) | |
| | | return eT(0); | |
| | | else | |
| | | return ret_val; | |
| | | } | |
| | | } | |
| | | | |
|
| ++it; | | template<typename T1> | |
| | | inline | |
| | | typename arma_cx_only<typename T1::elem_type>::result | |
| | | spop_min::min_with_index(const SpProxy<T1>& P, uword& index_of_min_val) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | typedef typename T1::elem_type eT; | |
| | | typedef typename get_pod_type<eT>::result T; | |
| | | | |
| | | const uword n_elem = P.get_n_elem(); | |
| | | const uword n_nonzero = P.get_n_nonzero(); | |
| | | const uword n_rows = P.get_n_rows(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "min(): given object has no elements"); | |
| | | | |
| | | T min_val = priv::most_pos<T>(); | |
| | | | |
|
| while(it != p.end()) | | if(SpProxy<T1>::must_use_iterator == true) | |
| | | { | |
| | | // We have to iterate over the elements. | |
| | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| { | | { | |
|
| eT val_orig = *it; | | const T tmp_val = std::abs(*it); | |
| T val_abs = std::abs(val_orig); | | | |
| | | | |
|
| if(val_abs < best_val_abs) | | if (tmp_val < min_val) | |
| { | | { | |
|
| best_val_abs = val_abs; | | min_val = tmp_val; | |
| best_val_orig = val_orig; | | index_of_min_val = it.row() + it.col() * n_rows; | |
| } | | } | |
| | | | |
| ++it; | | ++it; | |
| } | | } | |
|
| | | } | |
| | | else | |
| | | { | |
| | | // We can do direct access. | |
| | | min_val = std::abs(op_min::direct_min(P.get_values(), n_nonzero, index_ | |
| | | of_min_val)); | |
| | | | |
|
| if(p.get_n_nonzero() == p.get_n_elem()) | | // Convert to actual position in matrix. | |
| { | | const uword row = P.get_row_indices()[index_of_min_val]; | |
| return best_val_orig; | | uword col = 0; | |
| } | | while (P.get_col_ptrs()[++col] < index_of_min_val + 1) { } | |
| else | | index_of_min_val = (col - 1) * n_rows + row; | |
| | | } | |
| | | | |
| | | if(n_elem != n_nonzero) | |
| | | { | |
| | | min_val = std::min(T(0), min_val); | |
| | | | |
| | | // If the min_val is a nonzero element, we need its actual position in | |
| | | the matrix. | |
| | | if(min_val == T(0)) | |
| { | | { | |
|
| const eT val1 = eT(0); | | // Find first zero element. | |
| | | uword last_row = 0; | |
| | | uword last_col = 0; | |
| | | | |
|
| return ( std::abs(val1) < best_val_abs ) ? val1 : best_val_orig; | | typedef typename SpProxy<T1>::const_iterator_type it_type; | |
| | | | |
| | | it_type it = P.begin(); | |
| | | it_type it_end = P.end(); | |
| | | | |
| | | while (it != it_end) | |
| | | { | |
| | | // Have we moved more than one position from the last place? | |
| | | if ((it.col() == last_col) && (it.row() - last_row > 1)) | |
| | | { | |
| | | index_of_min_val = it.col() * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() >= last_col + 1) && (last_row < n_rows - 1)) | |
| | | { | |
| | | index_of_min_val = last_col * n_rows + last_row + 1; | |
| | | break; | |
| | | } | |
| | | else if ((it.col() == last_col + 1) && (it.row() > 0)) | |
| | | { | |
| | | index_of_min_val = it.col() * n_rows; | |
| | | break; | |
| | | } | |
| | | else if (it.col() > last_col + 1) | |
| | | { | |
| | | index_of_min_val = (last_col + 1) * n_rows; | |
| | | break; | |
| | | } | |
| | | | |
| | | last_row = it.row(); | |
| | | last_col = it.col(); | |
| | | ++it; | |
| | | } | |
| } | | } | |
| } | | } | |
|
| | | | |
| | | return P[index_of_min_val]; | |
| } | | } | |
| | | | |
| //! @} | | //! @} | |
| | | | |
End of changes. 52 change blocks. |
| 85 lines changed or deleted | | 391 lines changed or added | |
|
| subview_cube_meat.hpp | | subview_cube_meat.hpp | |
| | | | |
| skipping to change at line 284 | | skipping to change at line 284 | |
| { | | { | |
| arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic
e,col), t_n_rows ); | | arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic
e,col), t_n_rows ); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| //! x.subcube(...) = y.subcube(...) | | //! x.subcube(...) = y.subcube(...) | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview_cube<eT>::operator= (const subview_cube<eT>& x_in) | | subview_cube<eT>::operator= (const subview_cube<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Cube<eT> tmp(x); | |
| | | | |
| | | (*this).operator=(tmp); | |
| | | | |
|
| Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) | | return; | |
| : 0; | | } | |
| const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT> | | | |
| (*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i | | | |
| n.n_cols, x_in.n_slices) : 0; | | | |
| const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) | | | |
| : x_in; | | | |
| | | | |
| subview_cube<eT>& t = *this; | | subview_cube<eT>& t = *this; | |
| | | | |
| arma_debug_assert_same_size(t, x, "copy into subcube"); | | arma_debug_assert_same_size(t, x, "copy into subcube"); | |
| | | | |
| const uword t_n_rows = t.n_rows; | | const uword t_n_rows = t.n_rows; | |
| const uword t_n_cols = t.n_cols; | | const uword t_n_cols = t.n_cols; | |
| const uword t_n_slices = t.n_slices; | | const uword t_n_slices = t.n_slices; | |
| | | | |
| for(uword slice = 0; slice < t_n_slices; ++slice) | | for(uword slice = 0; slice < t_n_slices; ++slice) | |
| { | | { | |
| for(uword col = 0; col < t_n_cols; ++col) | | for(uword col = 0; col < t_n_cols; ++col) | |
| { | | { | |
| arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col),
t_n_rows ); | | arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col),
t_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview_cube; | | | |
| delete tmp_cube; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview_cube<eT>::operator+= (const subview_cube<eT>& x_in) | | subview_cube<eT>::operator+= (const subview_cube<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Cube<eT> tmp(x); | |
| | | | |
| | | (*this).operator+=(tmp); | |
| | | | |
|
| Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) | | return; | |
| : 0; | | } | |
| const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT> | | | |
| (*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i | | | |
| n.n_cols, x_in.n_slices) : 0; | | | |
| const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) | | | |
| : x_in; | | | |
| | | | |
| subview_cube<eT>& t = *this; | | subview_cube<eT>& t = *this; | |
| | | | |
| arma_debug_assert_same_size(t, x, "addition"); | | arma_debug_assert_same_size(t, x, "addition"); | |
| | | | |
| const uword t_n_rows = t.n_rows; | | const uword t_n_rows = t.n_rows; | |
| const uword t_n_cols = t.n_cols; | | const uword t_n_cols = t.n_cols; | |
| const uword t_n_slices = t.n_slices; | | const uword t_n_slices = t.n_slices; | |
| | | | |
| for(uword slice = 0; slice < t_n_slices; ++slice) | | for(uword slice = 0; slice < t_n_slices; ++slice) | |
| { | | { | |
| for(uword col = 0; col < t_n_cols; ++col) | | for(uword col = 0; col < t_n_cols; ++col) | |
| { | | { | |
| arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(sli
ce,col), t_n_rows ); | | arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(sli
ce,col), t_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview_cube; | | | |
| delete tmp_cube; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview_cube<eT>::operator-= (const subview_cube<eT>& x_in) | | subview_cube<eT>::operator-= (const subview_cube<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Cube<eT> tmp(x); | |
| | | | |
| | | (*this).operator-=(tmp); | |
| | | | |
|
| Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) | | return; | |
| : 0; | | } | |
| const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT> | | | |
| (*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i | | | |
| n.n_cols, x_in.n_slices) : 0; | | | |
| const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) | | | |
| : x_in; | | | |
| | | | |
| subview_cube<eT>& t = *this; | | subview_cube<eT>& t = *this; | |
| | | | |
| arma_debug_assert_same_size(t, x, "subtraction"); | | arma_debug_assert_same_size(t, x, "subtraction"); | |
| | | | |
| const uword t_n_rows = t.n_rows; | | const uword t_n_rows = t.n_rows; | |
| const uword t_n_cols = t.n_cols; | | const uword t_n_cols = t.n_cols; | |
| const uword t_n_slices = t.n_slices; | | const uword t_n_slices = t.n_slices; | |
| | | | |
| for(uword slice = 0; slice < t_n_slices; ++slice) | | for(uword slice = 0; slice < t_n_slices; ++slice) | |
| { | | { | |
| for(uword col = 0; col < t_n_cols; ++col) | | for(uword col = 0; col < t_n_cols; ++col) | |
| { | | { | |
| arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(sl
ice,col), t_n_rows ); | | arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(sl
ice,col), t_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview_cube; | | | |
| delete tmp_cube; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview_cube<eT>::operator%= (const subview_cube<eT>& x_in) | | subview_cube<eT>::operator%= (const subview_cube<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Cube<eT> tmp(x); | |
| | | | |
|
| Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) | | (*this).operator%=(tmp); | |
| : 0; | | | |
| const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT> | | return; | |
| (*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i | | } | |
| n.n_cols, x_in.n_slices) : 0; | | | |
| const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) | | | |
| : x_in; | | | |
| | | | |
| subview_cube<eT>& t = *this; | | subview_cube<eT>& t = *this; | |
| | | | |
| arma_debug_assert_same_size(t, x, "element-wise multiplication"); | | arma_debug_assert_same_size(t, x, "element-wise multiplication"); | |
| | | | |
| const uword t_n_rows = t.n_rows; | | const uword t_n_rows = t.n_rows; | |
| const uword t_n_cols = t.n_cols; | | const uword t_n_cols = t.n_cols; | |
| const uword t_n_slices = t.n_slices; | | const uword t_n_slices = t.n_slices; | |
| | | | |
| for(uword slice = 0; slice < t_n_slices; ++slice) | | for(uword slice = 0; slice < t_n_slices; ++slice) | |
| { | | { | |
| for(uword col = 0; col < t_n_cols; ++col) | | for(uword col = 0; col < t_n_cols; ++col) | |
| { | | { | |
| arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slic
e,col), t_n_rows ); | | arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slic
e,col), t_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview_cube; | | | |
| delete tmp_cube; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview_cube<eT>::operator/= (const subview_cube<eT>& x_in) | | subview_cube<eT>::operator/= (const subview_cube<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Cube<eT> tmp(x); | |
| | | | |
| | | (*this).operator/=(tmp); | |
| | | | |
|
| Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) | | return; | |
| : 0; | | } | |
| const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT> | | | |
| (*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_i | | | |
| n.n_cols, x_in.n_slices) : 0; | | | |
| const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) | | | |
| : x_in; | | | |
| | | | |
| subview_cube<eT>& t = *this; | | subview_cube<eT>& t = *this; | |
| | | | |
| arma_debug_assert_same_size(t, x, "element-wise division"); | | arma_debug_assert_same_size(t, x, "element-wise division"); | |
| | | | |
| const uword t_n_rows = t.n_rows; | | const uword t_n_rows = t.n_rows; | |
| const uword t_n_cols = t.n_cols; | | const uword t_n_cols = t.n_cols; | |
| const uword t_n_slices = t.n_slices; | | const uword t_n_slices = t.n_slices; | |
| | | | |
| for(uword slice = 0; slice < t_n_slices; ++slice) | | for(uword slice = 0; slice < t_n_slices; ++slice) | |
| { | | { | |
| for(uword col = 0; col < t_n_cols; ++col) | | for(uword col = 0; col < t_n_cols; ++col) | |
| { | | { | |
| arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic
e,col), t_n_rows ); | | arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slic
e,col), t_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview_cube; | | | |
| delete tmp_cube; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| void | | void | |
| subview_cube<eT>::operator= (const Base<eT,T1>& in) | | subview_cube<eT>::operator= (const Base<eT,T1>& in) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| | | | |
| skipping to change at line 1119 | | skipping to change at line 1099 | |
| { | | { | |
| for(uword col = 0; col < local_n_cols; ++col) | | for(uword col = 0; col < local_n_cols; ++col) | |
| { | | { | |
| arma_rng::randn<eT>::fill( slice_colptr(slice,col), local_n_rows ); | | arma_rng::randn<eT>::fill( slice_colptr(slice,col), local_n_rows ); | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
|
| | | arma_warn_unused | |
| | | eT | |
| | | subview_cube<eT>::min() const | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "subview_cube::min(): object has no elem | |
| | | ents" ); | |
| | | | |
| | | const uword local_n_rows = n_rows; | |
| | | const uword local_n_cols = n_cols; | |
| | | const uword local_n_slices = n_slices; | |
| | | | |
| | | eT min_val = at(0,0,0); | |
| | | | |
| | | for(uword si=0; si < local_n_slices; ++si) | |
| | | for(uword ci=0; ci < local_n_cols; ++ci) | |
| | | { | |
| | | min_val = (std::min)( min_val, op_min::direct_min(slice_colptr(si,ci), | |
| | | local_n_rows) ); | |
| | | } | |
| | | | |
| | | return min_val; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| | | arma_warn_unused | |
| | | eT | |
| | | subview_cube<eT>::max() const | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | arma_debug_check( (n_elem == 0), "subview_cube::max(): object has no elem | |
| | | ents" ); | |
| | | | |
| | | const uword local_n_rows = n_rows; | |
| | | const uword local_n_cols = n_cols; | |
| | | const uword local_n_slices = n_slices; | |
| | | | |
| | | eT max_val = at(0,0,0); | |
| | | | |
| | | for(uword si=0; si < local_n_slices; ++si) | |
| | | for(uword ci=0; ci < local_n_cols; ++ci) | |
| | | { | |
| | | max_val = (std::max)( max_val, op_max::direct_max(slice_colptr(si,ci), | |
| | | local_n_rows) ); | |
| | | } | |
| | | | |
| | | return max_val; | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| | | inline | |
| eT | | eT | |
| subview_cube<eT>::at_alt(const uword i) const | | subview_cube<eT>::at_alt(const uword i) const | |
| { | | { | |
| return operator[](i); | | return operator[](i); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| eT& | | eT& | |
| subview_cube<eT>::operator[](const uword i) | | subview_cube<eT>::operator[](const uword i) | |
| | | | |
End of changes. 21 change blocks. |
| 80 lines changed or deleted | | 94 lines changed or added | |
|
| subview_meat.hpp | | subview_meat.hpp | |
| | | | |
| skipping to change at line 849 | | skipping to change at line 849 | |
| for (uword r = 0; r < n_rows; ++r) | | for (uword r = 0; r < n_rows; ++r) | |
| { | | { | |
| at(r, c) /= p.at(r, c); | | at(r, c) /= p.at(r, c); | |
| } | | } | |
| } | | } | |
| | | | |
| //! x.submat(...) = y.submat(...) | | //! x.submat(...) = y.submat(...) | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview<eT>::operator= (const subview<eT>& x_in) | | subview<eT>::operator= (const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Mat<eT> tmp(x); | |
| | | | |
| | | (*this).operator=(tmp); | |
| | | | |
|
| Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; | | return; | |
| const subview<eT>* tmp_subview = overlap ? new subview<eT>(*tmp_mat, x_in | | } | |
| .aux_row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0; | | | |
| const subview<eT>& x = overlap ? (*tmp_subview) : x_in; | | | |
| | | | |
| subview<eT>& s = *this; | | subview<eT>& s = *this; | |
| | | | |
| arma_debug_assert_same_size(s, x, "copy into submatrix"); | | arma_debug_assert_same_size(s, x, "copy into submatrix"); | |
| | | | |
| const uword s_n_cols = s.n_cols; | | const uword s_n_cols = s.n_cols; | |
| const uword s_n_rows = s.n_rows; | | const uword s_n_rows = s.n_rows; | |
| | | | |
| if(s_n_rows == 1) | | if(s_n_rows == 1) | |
| { | | { | |
| | | | |
| skipping to change at line 899 | | skipping to change at line 902 | |
| A.at(row_A, start_col_A + ii) = B.at(row_B, start_col_B + ii); | | A.at(row_A, start_col_A + ii) = B.at(row_B, start_col_B + ii); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| for(uword ucol=0; ucol < s_n_cols; ++ucol) | | for(uword ucol=0; ucol < s_n_cols; ++ucol) | |
| { | | { | |
| arrayops::copy( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | | arrayops::copy( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview; | | | |
| delete tmp_mat; | | | |
| } | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview<eT>::operator+= (const subview<eT>& x_in) | | subview<eT>::operator+= (const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Mat<eT> tmp(x); | |
| | | | |
| | | (*this).operator+=(tmp); | |
| | | | |
|
| Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; | | return; | |
| const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux | | } | |
| _row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0; | | | |
| const subview<eT>& x = overlap ? (*tmp_subview) : x_in; | | | |
| | | | |
| subview<eT>& s = *this; | | subview<eT>& s = *this; | |
| | | | |
| arma_debug_assert_same_size(s, x, "addition"); | | arma_debug_assert_same_size(s, x, "addition"); | |
| | | | |
| const uword s_n_rows = s.n_rows; | | const uword s_n_rows = s.n_rows; | |
| const uword s_n_cols = s.n_cols; | | const uword s_n_cols = s.n_cols; | |
| | | | |
| if(s_n_rows == 1) | | if(s_n_rows == 1) | |
| { | | { | |
| | | | |
| skipping to change at line 961 | | skipping to change at line 961 | |
| A.at(row_A, start_col_A + ii) += B.at(row_B, start_col_B + ii); | | A.at(row_A, start_col_A + ii) += B.at(row_B, start_col_B + ii); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| for(uword ucol=0; ucol < s_n_cols; ++ucol) | | for(uword ucol=0; ucol < s_n_cols; ++ucol) | |
| { | | { | |
| arrayops::inplace_plus( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | | arrayops::inplace_plus( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview; | | | |
| delete tmp_mat; | | | |
| } | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview<eT>::operator-= (const subview<eT>& x_in) | | subview<eT>::operator-= (const subview<eT>& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Mat<eT> tmp(x); | |
| | | | |
| | | (*this).operator-=(tmp); | |
| | | | |
|
| Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; | | return; | |
| const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux | | } | |
| _row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0; | | | |
| const subview<eT>& x = overlap ? (*tmp_subview) : x_in; | | | |
| | | | |
| subview<eT>& s = *this; | | subview<eT>& s = *this; | |
| | | | |
| arma_debug_assert_same_size(s, x, "subtraction"); | | arma_debug_assert_same_size(s, x, "subtraction"); | |
| | | | |
| const uword s_n_rows = s.n_rows; | | const uword s_n_rows = s.n_rows; | |
| const uword s_n_cols = s.n_cols; | | const uword s_n_cols = s.n_cols; | |
| | | | |
| if(s_n_rows == 1) | | if(s_n_rows == 1) | |
| { | | { | |
| | | | |
| skipping to change at line 1022 | | skipping to change at line 1019 | |
| A.at(row_A, start_col_A + ii) -= B.at(row_B, start_col_B + ii); | | A.at(row_A, start_col_A + ii) -= B.at(row_B, start_col_B + ii); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| for(uword ucol=0; ucol < s_n_cols; ++ucol) | | for(uword ucol=0; ucol < s_n_cols; ++ucol) | |
| { | | { | |
| arrayops::inplace_minus( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | | arrayops::inplace_minus( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview; | | | |
| delete tmp_mat; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview<eT>::operator%= (const subview& x_in) | | subview<eT>::operator%= (const subview& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Mat<eT> tmp(x); | |
| | | | |
| | | (*this).operator%=(tmp); | |
| | | | |
|
| Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; | | return; | |
| const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux | | } | |
| _row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0; | | | |
| const subview<eT>& x = overlap ? (*tmp_subview) : x_in; | | | |
| | | | |
| subview<eT>& s = *this; | | subview<eT>& s = *this; | |
| | | | |
| arma_debug_assert_same_size(s, x, "element-wise multiplication"); | | arma_debug_assert_same_size(s, x, "element-wise multiplication"); | |
| | | | |
| const uword s_n_rows = s.n_rows; | | const uword s_n_rows = s.n_rows; | |
| const uword s_n_cols = s.n_cols; | | const uword s_n_cols = s.n_cols; | |
| | | | |
| if(s_n_rows == 1) | | if(s_n_rows == 1) | |
| { | | { | |
| | | | |
| skipping to change at line 1084 | | skipping to change at line 1077 | |
| A.at(row_A, start_col_A + ii) *= B.at(row_B, start_col_B + ii); | | A.at(row_A, start_col_A + ii) *= B.at(row_B, start_col_B + ii); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| for(uword ucol=0; ucol < s_n_cols; ++ucol) | | for(uword ucol=0; ucol < s_n_cols; ++ucol) | |
| { | | { | |
| arrayops::inplace_mul( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | | arrayops::inplace_mul( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview; | | | |
| delete tmp_mat; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
|
| subview<eT>::operator/= (const subview& x_in) | | subview<eT>::operator/= (const subview& x) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
|
| const bool overlap = check_overlap(x_in); | | if(check_overlap(x)) | |
| | | { | |
| | | const Mat<eT> tmp(x); | |
| | | | |
| | | (*this).operator/=(tmp); | |
| | | | |
|
| Mat<eT>* tmp_mat = overlap ? new Mat<eT>(x_in.m) : 0; | | return; | |
| const subview<eT>* tmp_subview = overlap ? new subview(*tmp_mat, x_in.aux | | } | |
| _row1, x_in.aux_col1, x_in.n_rows, x_in.n_cols) : 0; | | | |
| const subview<eT>& x = overlap ? (*tmp_subview) : x_in; | | | |
| | | | |
| subview<eT>& s = *this; | | subview<eT>& s = *this; | |
| | | | |
| arma_debug_assert_same_size(s, x, "element-wise division"); | | arma_debug_assert_same_size(s, x, "element-wise division"); | |
| | | | |
| const uword s_n_rows = s.n_rows; | | const uword s_n_rows = s.n_rows; | |
| const uword s_n_cols = s.n_cols; | | const uword s_n_cols = s.n_cols; | |
| | | | |
| if(s_n_rows == 1) | | if(s_n_rows == 1) | |
| { | | { | |
| | | | |
| skipping to change at line 1146 | | skipping to change at line 1135 | |
| A.at(row_A, start_col_A + ii) /= B.at(row_B, start_col_B + ii); | | A.at(row_A, start_col_A + ii) /= B.at(row_B, start_col_B + ii); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
| for(uword ucol=0; ucol < s_n_cols; ++ucol) | | for(uword ucol=0; ucol < s_n_cols; ++ucol) | |
| { | | { | |
| arrayops::inplace_div( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | | arrayops::inplace_div( s.colptr(ucol), x.colptr(ucol), s_n_rows ); | |
| } | | } | |
| } | | } | |
|
| | | | |
| if(overlap) | | | |
| { | | | |
| delete tmp_subview; | | | |
| delete tmp_mat; | | | |
| } | | | |
| | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1, typename gen_type> | | template<typename T1, typename gen_type> | |
| inline | | inline | |
| typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void>
::result | | typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void>
::result | |
| subview<eT>::operator= (const Gen<T1,gen_type>& in) | | subview<eT>::operator= (const Gen<T1,gen_type>& in) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| | | | |
End of changes. 20 change blocks. |
| 63 lines changed or deleted | | 40 lines changed or added | |
|