Chris@49: // Copyright (C) 2011-2013 Ryan Curtin Chris@49: // Copyright (C) 2012-2013 Conrad Sanderson Chris@49: // Copyright (C) 2011 Matthew Amidon Chris@49: // Chris@49: // This Source Code Form is subject to the terms of the Mozilla Public Chris@49: // License, v. 2.0. If a copy of the MPL was not distributed with this Chris@49: // file, You can obtain one at http://mozilla.org/MPL/2.0/. Chris@49: Chris@49: //! \addtogroup SpMat Chris@49: //! @{ Chris@49: Chris@49: //! Sparse matrix class, with data stored in compressed sparse column (CSC) format Chris@49: Chris@49: template Chris@49: class SpMat : public SpBase< eT, SpMat > Chris@49: { Chris@49: public: Chris@49: Chris@49: typedef eT elem_type; //!< the type of elements stored in the matrix Chris@49: typedef typename get_pod_type::result pod_type; //!< if eT is non-complex, pod_type is the same as eT; otherwise, pod_type is the underlying type used by std::complex Chris@49: Chris@49: static const bool is_row = false; Chris@49: static const bool is_col = false; Chris@49: Chris@49: const uword n_rows; //!< number of rows in the matrix (read-only) Chris@49: const uword n_cols; //!< number of columns in the matrix (read-only) Chris@49: const uword n_elem; //!< number of elements in the matrix (read-only) Chris@49: const uword n_nonzero; //!< number of nonzero elements in the matrix (read-only) Chris@49: const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector Chris@49: Chris@49: // So that SpValProxy can call add_element() and delete_element(). Chris@49: friend class SpValProxy >; Chris@49: friend class SpSubview; Chris@49: Chris@49: /** Chris@49: * The memory used to store the values of the matrix. Chris@49: * In accordance with the CSC format, this stores only the actual values. Chris@49: * The correct locations of the values are assembled from the row indices Chris@49: * and the column pointers. Chris@49: */ Chris@49: const eT* const values; Chris@49: Chris@49: /** Chris@49: * The row indices of each value. row_indices[i] is the row of values[i]. Chris@49: * The length of this array is n_nonzero + 1; the final value ensures the Chris@49: * integrity of iterators. Chris@49: */ Chris@49: const uword* const row_indices; Chris@49: Chris@49: /** Chris@49: * The column pointers. This stores the index of the first item in column i. Chris@49: * That is, values[col_ptrs[i]] is the first value in column i, and it is in Chris@49: * row row_indices[col_ptrs[i]]. Chris@49: */ Chris@49: const uword* const col_ptrs; Chris@49: Chris@49: inline SpMat(); //! Size will be 0x0 (empty). Chris@49: inline ~SpMat(); Chris@49: Chris@49: inline SpMat(const uword in_rows, const uword in_cols); Chris@49: Chris@49: inline SpMat(const char* text); Chris@49: inline const SpMat& operator=(const char* text); Chris@49: inline SpMat(const std::string& text); Chris@49: inline const SpMat& operator=(const std::string& text); Chris@49: inline SpMat(const SpMat& x); Chris@49: Chris@49: template inline SpMat(const Base& locations, const Base& values, const bool sort_locations = true); Chris@49: template inline SpMat(const Base& locations, const Base& values, const uword n_rows, const uword n_cols, const bool sort_locations = true); Chris@49: Chris@49: inline const SpMat& operator=(const eT val); //! Sets size to 1x1. Chris@49: inline const SpMat& operator*=(const eT val); Chris@49: inline const SpMat& operator/=(const eT val); Chris@49: // operator+=(val) and operator-=(val) are not defined as they don't make sense for sparse matrices Chris@49: Chris@49: /** Chris@49: * Operators on other sparse matrices. These work as though you would expect. Chris@49: */ Chris@49: inline const SpMat& operator=(const SpMat& m); Chris@49: inline const SpMat& operator+=(const SpMat& m); Chris@49: inline const SpMat& operator-=(const SpMat& m); Chris@49: inline const SpMat& operator*=(const SpMat& m); Chris@49: inline const SpMat& operator%=(const SpMat& m); Chris@49: inline const SpMat& operator/=(const SpMat& m); Chris@49: Chris@49: /** Chris@49: * Operators on other regular matrices. These work as though you would expect. Chris@49: */ Chris@49: template inline explicit SpMat(const Base& m); Chris@49: template inline const SpMat& operator=(const Base& m); Chris@49: template inline const SpMat& operator*=(const Base& m); Chris@49: template inline const SpMat& operator/=(const Base& m); Chris@49: template inline const SpMat& operator%=(const Base& m); Chris@49: Chris@49: Chris@49: //! construction of complex matrix out of two non-complex matrices; Chris@49: template Chris@49: inline explicit SpMat(const SpBase& A, const SpBase& B); Chris@49: Chris@49: /** Chris@49: * Operations on sparse subviews. Chris@49: */ Chris@49: inline SpMat(const SpSubview& X); Chris@49: inline const SpMat& operator=(const SpSubview& X); Chris@49: inline const SpMat& operator+=(const SpSubview& X); Chris@49: inline const SpMat& operator-=(const SpSubview& X); Chris@49: inline const SpMat& operator*=(const SpSubview& X); Chris@49: inline const SpMat& operator%=(const SpSubview& X); Chris@49: inline const SpMat& operator/=(const SpSubview& X); Chris@49: Chris@49: /** Chris@49: * Operations on regular subviews. Chris@49: */ Chris@49: inline SpMat(const subview& x); Chris@49: inline const SpMat& operator=(const subview& x); Chris@49: inline const SpMat& operator+=(const subview& x); Chris@49: inline const SpMat& operator-=(const subview& x); Chris@49: inline const SpMat& operator*=(const subview& x); Chris@49: inline const SpMat& operator%=(const subview& x); Chris@49: inline const SpMat& operator/=(const subview& x); Chris@49: Chris@49: Chris@49: // delayed unary ops Chris@49: template inline SpMat(const SpOp& X); Chris@49: template inline const SpMat& operator=(const SpOp& X); Chris@49: template inline const SpMat& operator+=(const SpOp& X); Chris@49: template inline const SpMat& operator-=(const SpOp& X); Chris@49: template inline const SpMat& operator*=(const SpOp& X); Chris@49: template inline const SpMat& operator%=(const SpOp& X); Chris@49: template inline const SpMat& operator/=(const SpOp& X); Chris@49: Chris@49: // delayed binary ops Chris@49: template inline SpMat(const SpGlue& X); Chris@49: template inline const SpMat& operator=(const SpGlue& X); Chris@49: template inline const SpMat& operator+=(const SpGlue& X); Chris@49: template inline const SpMat& operator-=(const SpGlue& X); Chris@49: template inline const SpMat& operator*=(const SpGlue& X); Chris@49: template inline const SpMat& operator%=(const SpGlue& X); Chris@49: template inline const SpMat& operator/=(const SpGlue& X); Chris@49: Chris@49: // delayed mixted-type unary ops Chris@49: template inline SpMat(const mtSpOp& X); Chris@49: template inline const SpMat& operator=(const mtSpOp& X); Chris@49: template inline const SpMat& operator+=(const mtSpOp& X); Chris@49: template inline const SpMat& operator-=(const mtSpOp& X); Chris@49: template inline const SpMat& operator*=(const mtSpOp& X); Chris@49: template inline const SpMat& operator%=(const mtSpOp& X); Chris@49: template inline const SpMat& operator/=(const mtSpOp& X); Chris@49: Chris@49: /** Chris@49: * Submatrix methods. Chris@49: */ Chris@49: arma_inline SpSubview row(const uword row_num); Chris@49: arma_inline const SpSubview row(const uword row_num) const; Chris@49: Chris@49: inline SpSubview operator()(const uword row_num, const span& col_span); Chris@49: inline const SpSubview operator()(const uword row_num, const span& col_span) const; Chris@49: Chris@49: Chris@49: arma_inline SpSubview col(const uword col_num); Chris@49: arma_inline const SpSubview col(const uword col_num) const; Chris@49: Chris@49: inline SpSubview operator()(const span& row_span, const uword col_num); Chris@49: inline const SpSubview operator()(const span& row_span, const uword col_num) const; Chris@49: Chris@49: /** Chris@49: * Row- and column-related functions. Chris@49: */ Chris@49: inline void swap_rows(const uword in_row1, const uword in_row2); Chris@49: inline void swap_cols(const uword in_col1, const uword in_col2); Chris@49: Chris@49: inline void shed_row(const uword row_num); Chris@49: inline void shed_col(const uword col_num); Chris@49: Chris@49: inline void shed_rows(const uword in_row1, const uword in_row2); Chris@49: inline void shed_cols(const uword in_col1, const uword in_col2); Chris@49: Chris@49: arma_inline SpSubview rows(const uword in_row1, const uword in_row2); Chris@49: arma_inline const SpSubview rows(const uword in_row1, const uword in_row2) const; Chris@49: Chris@49: arma_inline SpSubview cols(const uword in_col1, const uword in_col2); Chris@49: arma_inline const SpSubview cols(const uword in_col1, const uword in_col2) const; Chris@49: Chris@49: arma_inline SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2); Chris@49: arma_inline const SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const; Chris@49: Chris@49: Chris@49: inline SpSubview submat (const span& row_span, const span& col_span); Chris@49: inline const SpSubview submat (const span& row_span, const span& col_span) const; Chris@49: Chris@49: inline SpSubview operator()(const span& row_span, const span& col_span); Chris@49: inline const SpSubview operator()(const span& row_span, const span& col_span) const; Chris@49: Chris@49: /** Chris@49: * Element access; access the i'th element (works identically to the Mat accessors). Chris@49: * If there is nothing at element i, 0 is returned. Chris@49: * Chris@49: * @param i Element to access. Chris@49: */ Chris@49: arma_inline arma_warn_unused SpValProxy > operator[] (const uword i); Chris@49: arma_inline arma_warn_unused eT operator[] (const uword i) const; Chris@49: arma_inline arma_warn_unused SpValProxy > at (const uword i); Chris@49: arma_inline arma_warn_unused eT at (const uword i) const; Chris@49: arma_inline arma_warn_unused SpValProxy > operator() (const uword i); Chris@49: arma_inline arma_warn_unused eT operator() (const uword i) const; Chris@49: Chris@49: /** Chris@49: * Element access; access the element at row in_row and column in_col. Chris@49: * If there is nothing at that position, 0 is returned. Chris@49: */ Chris@49: arma_inline arma_warn_unused SpValProxy > at (const uword in_row, const uword in_col); Chris@49: arma_inline arma_warn_unused eT at (const uword in_row, const uword in_col) const; Chris@49: arma_inline arma_warn_unused SpValProxy > operator() (const uword in_row, const uword in_col); Chris@49: arma_inline arma_warn_unused eT operator() (const uword in_row, const uword in_col) const; Chris@49: Chris@49: Chris@49: /** Chris@49: * Information boolean checks on matrices. Chris@49: */ Chris@49: arma_inline arma_warn_unused bool is_empty() const; Chris@49: arma_inline arma_warn_unused bool is_vec() const; Chris@49: arma_inline arma_warn_unused bool is_rowvec() const; Chris@49: arma_inline arma_warn_unused bool is_colvec() const; Chris@49: arma_inline arma_warn_unused bool is_square() const; Chris@49: inline arma_warn_unused bool is_finite() const; Chris@49: Chris@49: arma_inline arma_warn_unused bool in_range(const uword i) const; Chris@49: arma_inline arma_warn_unused bool in_range(const span& x) const; Chris@49: Chris@49: arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col) const; Chris@49: arma_inline arma_warn_unused bool in_range(const span& row_span, const uword in_col) const; Chris@49: arma_inline arma_warn_unused bool in_range(const uword in_row, const span& col_span) const; Chris@49: arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const; Chris@49: Chris@49: /** Chris@49: * Printing the matrix. Chris@49: * Chris@49: * @param extra_text Text to prepend to output. Chris@49: */ Chris@49: inline void impl_print(const std::string& extra_text) const; Chris@49: inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const; Chris@49: Chris@49: inline void impl_raw_print(const std::string& extra_text) const; Chris@49: inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const; Chris@49: Chris@49: inline void impl_print_dense(const std::string& extra_text) const; Chris@49: inline void impl_print_dense(std::ostream& user_stream, const std::string& extra_text) const; Chris@49: Chris@49: inline void impl_raw_print_dense(const std::string& extra_text) const; Chris@49: inline void impl_raw_print_dense(std::ostream& user_stream, const std::string& extra_text) const; Chris@49: Chris@49: //! Copy the size of another matrix. Chris@49: template inline void copy_size(const SpMat& m); Chris@49: template inline void copy_size(const Mat& m); Chris@49: Chris@49: /** Chris@49: * Resize the matrix to a given size. The matrix will be resized to be a column vector (i.e. in_elem columns, 1 row). Chris@49: * Chris@49: * @param in_elem Number of elements to allow. Chris@49: */ Chris@49: inline void set_size(const uword in_elem); Chris@49: Chris@49: /** Chris@49: * Resize the matrix to a given size. Chris@49: * Chris@49: * @param in_rows Number of rows to allow. Chris@49: * @param in_cols Number of columns to allow. Chris@49: */ Chris@49: inline void set_size(const uword in_rows, const uword in_cols); Chris@49: Chris@49: inline void reshape(const uword in_rows, const uword in_cols, const uword dim = 0); Chris@49: Chris@49: inline const SpMat& zeros(); Chris@49: inline const SpMat& zeros(const uword in_elem); Chris@49: inline const SpMat& zeros(const uword in_rows, const uword in_cols); Chris@49: Chris@49: inline const SpMat& eye(); Chris@49: inline const SpMat& eye(const uword in_rows, const uword in_cols); Chris@49: Chris@49: inline const SpMat& speye(); Chris@49: inline const SpMat& speye(const uword in_rows, const uword in_cols); Chris@49: Chris@49: inline const SpMat& sprandu(const uword in_rows, const uword in_cols, const double density); Chris@49: inline const SpMat& sprandn(const uword in_rows, const uword in_cols, const double density); Chris@49: Chris@49: inline void reset(); Chris@49: Chris@49: /** Chris@49: * Get the minimum or maximum of the matrix. Chris@49: */ Chris@49: inline arma_warn_unused eT min() const; Chris@49: inline eT min(uword& index_of_min_val) const; Chris@49: inline eT min(uword& row_of_min_val, uword& col_of_min_val) const; Chris@49: Chris@49: inline arma_warn_unused eT max() const; Chris@49: inline eT max(uword& index_of_max_val) const; Chris@49: inline eT max(uword& row_of_min_val, uword& col_of_min_val) const; Chris@49: Chris@49: Chris@49: // saving and loading Chris@49: Chris@49: inline bool save(const std::string name, const file_type type = arma_binary, const bool print_status = true) const; Chris@49: inline bool save( std::ostream& os, const file_type type = arma_binary, const bool print_status = true) const; Chris@49: Chris@49: inline bool load(const std::string name, const file_type type = arma_binary, const bool print_status = true); Chris@49: inline bool load( std::istream& is, const file_type type = arma_binary, const bool print_status = true); Chris@49: Chris@49: inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; Chris@49: inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; Chris@49: Chris@49: inline bool quiet_load(const std::string name, const file_type type = arma_binary); Chris@49: inline bool quiet_load( std::istream& is, const file_type type = arma_binary); Chris@49: Chris@49: // TODO: speed up loading of sparse matrices stored as text files (ie. raw_ascii and coord_ascii) Chris@49: // TODO: implement auto_detect for sparse matrices Chris@49: // TODO: modify docs to specify which formats are not applicable to sparse matrices Chris@49: Chris@49: Chris@49: // These forward declarations are necessary. Chris@49: class iterator_base; Chris@49: class iterator; Chris@49: class const_iterator; Chris@49: class row_iterator; Chris@49: class const_row_iterator; Chris@49: Chris@49: // Iterator base provides basic operators but not how to compare or how to Chris@49: // iterate. Chris@49: class iterator_base Chris@49: { Chris@49: public: Chris@49: Chris@49: inline iterator_base(const SpMat& in_M); Chris@49: inline iterator_base(const SpMat& in_M, const uword col, const uword pos); Chris@49: Chris@49: inline arma_hot eT operator*() const; Chris@49: Chris@49: // Don't hold location internally; call "dummy" methods to get that information. Chris@49: arma_inline uword row() const { return M.row_indices[internal_pos]; } Chris@49: arma_inline uword col() const { return internal_col; } Chris@49: arma_inline uword pos() const { return internal_pos; } Chris@49: Chris@49: arma_aligned const SpMat& M; Chris@49: arma_aligned uword internal_col; Chris@49: arma_aligned uword internal_pos; Chris@49: Chris@49: // So that we satisfy the STL iterator types. Chris@49: typedef std::bidirectional_iterator_tag iterator_category; Chris@49: typedef eT value_type; Chris@49: typedef uword difference_type; // not certain on this one Chris@49: typedef const eT* pointer; Chris@49: typedef const eT& reference; Chris@49: }; Chris@49: Chris@49: class const_iterator : public iterator_base Chris@49: { Chris@49: public: Chris@49: Chris@49: inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Assumes initial_pos is valid. Chris@49: //! Once initialized, will be at the first nonzero value after the given position (using forward columnwise traversal). Chris@49: inline const_iterator(const SpMat& in_M, uword in_row, uword in_col); Chris@49: //! If you know the exact position of the iterator. in_row is a dummy argument. Chris@49: inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uword in_pos); Chris@49: inline const_iterator(const const_iterator& other); Chris@49: Chris@49: inline arma_hot const_iterator& operator++(); Chris@49: inline arma_hot const_iterator operator++(int); Chris@49: Chris@49: inline arma_hot const_iterator& operator--(); Chris@49: inline arma_hot const_iterator operator--(int); Chris@49: Chris@49: inline arma_hot bool operator==(const const_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const const_iterator& rhs) const; Chris@49: Chris@49: inline arma_hot bool operator==(const typename SpSubview::const_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const typename SpSubview::const_iterator& rhs) const; Chris@49: Chris@49: inline arma_hot bool operator==(const const_row_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const const_row_iterator& rhs) const; Chris@49: Chris@49: inline arma_hot bool operator==(const typename SpSubview::const_row_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const typename SpSubview::const_row_iterator& rhs) const; Chris@49: }; Chris@49: Chris@49: /** Chris@49: * So that we can iterate over nonzero values, we need an iterator Chris@49: * implementation. This can't be as simple as Mat's, which is just a pointer Chris@49: * to an eT. If a value is set to 0 using this iterator, the iterator is no Chris@49: * longer valid! Chris@49: */ Chris@49: class iterator : public const_iterator Chris@49: { Chris@49: public: Chris@49: Chris@49: inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in_M, initial_pos) { } Chris@49: inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterator(in_M, in_row, in_col) { } Chris@49: inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos) : const_iterator(in_M, in_row, in_col, in_pos) { } Chris@49: inline iterator(const const_iterator& other) : const_iterator(other) { } Chris@49: Chris@49: inline arma_hot SpValProxy > operator*(); Chris@49: Chris@49: // overloads needed for return type correctness Chris@49: inline arma_hot iterator& operator++(); Chris@49: inline arma_hot iterator operator++(int); Chris@49: Chris@49: inline arma_hot iterator& operator--(); Chris@49: inline arma_hot iterator operator--(int); Chris@49: Chris@49: // This has a different value_type than iterator_base. Chris@49: typedef SpValProxy > value_type; Chris@49: typedef const SpValProxy >* pointer; Chris@49: typedef const SpValProxy >& reference; Chris@49: }; Chris@49: Chris@49: class const_row_iterator : public iterator_base Chris@49: { Chris@49: public: Chris@49: Chris@49: inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0); Chris@49: //! Once initialized, will be at the first nonzero value after the given position (using forward row-wise traversal). Chris@49: inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col); Chris@49: inline const_row_iterator(const const_row_iterator& other); Chris@49: Chris@49: inline arma_hot const_row_iterator& operator++(); Chris@49: inline arma_hot const_row_iterator operator++(int); Chris@49: Chris@49: inline arma_hot const_row_iterator& operator--(); Chris@49: inline arma_hot const_row_iterator operator--(int); Chris@49: Chris@49: uword internal_row; // Hold row internally because we use internal_pos differently. Chris@49: uword actual_pos; // Actual position in matrix. Chris@49: Chris@49: arma_inline eT operator*() const { return iterator_base::M.values[actual_pos]; } Chris@49: Chris@49: arma_inline uword row() const { return internal_row; } Chris@49: Chris@49: inline arma_hot bool operator==(const const_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const const_iterator& rhs) const; Chris@49: Chris@49: inline arma_hot bool operator==(const typename SpSubview::const_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const typename SpSubview::const_iterator& rhs) const; Chris@49: Chris@49: inline arma_hot bool operator==(const const_row_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const const_row_iterator& rhs) const; Chris@49: Chris@49: inline arma_hot bool operator==(const typename SpSubview::const_row_iterator& rhs) const; Chris@49: inline arma_hot bool operator!=(const typename SpSubview::const_row_iterator& rhs) const; Chris@49: }; Chris@49: Chris@49: class row_iterator : public const_row_iterator Chris@49: { Chris@49: public: Chris@49: Chris@49: inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { } Chris@49: //! Once initialized, will be at the first nonzero value after the given position (using forward row-wise traversal). Chris@49: inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { } Chris@49: inline row_iterator(const row_iterator& other) : const_row_iterator(other) { } Chris@49: Chris@49: inline arma_hot SpValProxy > operator*(); Chris@49: Chris@49: // overloads required for return type correctness Chris@49: inline arma_hot row_iterator& operator++(); Chris@49: inline arma_hot row_iterator operator++(int); Chris@49: Chris@49: inline arma_hot row_iterator& operator--(); Chris@49: inline arma_hot row_iterator operator--(int); Chris@49: Chris@49: // This has a different value_type than iterator_base. Chris@49: typedef SpValProxy > value_type; Chris@49: typedef const SpValProxy >* pointer; Chris@49: typedef const SpValProxy >& reference; Chris@49: }; Chris@49: Chris@49: inline iterator begin(); Chris@49: inline const_iterator begin() const; Chris@49: Chris@49: inline iterator end(); Chris@49: inline const_iterator end() const; Chris@49: Chris@49: inline iterator begin_col(const uword col_num); Chris@49: inline const_iterator begin_col(const uword col_num) const; Chris@49: Chris@49: inline iterator end_col(const uword col_num); Chris@49: inline const_iterator end_col(const uword col_num) const; Chris@49: Chris@49: inline row_iterator begin_row(const uword row_num = 0); Chris@49: inline const_row_iterator begin_row(const uword row_num = 0) const; Chris@49: Chris@49: inline row_iterator end_row(); Chris@49: inline const_row_iterator end_row() const; Chris@49: Chris@49: inline row_iterator end_row(const uword row_num); Chris@49: inline const_row_iterator end_row(const uword row_num) const; Chris@49: Chris@49: inline void clear(); Chris@49: inline bool empty() const; Chris@49: inline uword size() const; Chris@49: Chris@49: /** Chris@49: * Resize memory. You are responsible for updating the column pointers and Chris@49: * filling the new memory (if the new size is larger). If the new size is Chris@49: * smaller, the first new_n_nonzero elements will be copied. n_nonzero is Chris@49: * updated. Chris@49: */ Chris@49: inline void mem_resize(const uword new_n_nonzero); Chris@49: Chris@49: //! don't use this unless you're writing internal Armadillo code Chris@49: inline void steal_mem(SpMat& X); Chris@49: Chris@49: //! don't use this unless you're writing internal Armadillo code Chris@49: template< typename T1, typename Functor> arma_hot inline void init_xform (const SpBase& x, const Functor& func); Chris@49: template arma_hot inline void init_xform_mt(const SpBase& x, const Functor& func); Chris@49: Chris@49: Chris@49: protected: Chris@49: Chris@49: /** Chris@49: * Initialize the matrix to the specified size. Data is not preserved, so the matrix is assumed to be entirely sparse (empty). Chris@49: */ Chris@49: inline void init(uword in_rows, uword in_cols); Chris@49: Chris@49: /** Chris@49: * Initialize the matrix from text. Data is (of course) not preserved, and Chris@49: * the size will be reset. Chris@49: */ Chris@49: inline void init(const std::string& text); Chris@49: Chris@49: /** Chris@49: * Initialize from another matrix (copy). Chris@49: */ Chris@49: inline void init(const SpMat& x); Chris@49: Chris@49: Chris@49: private: Chris@49: Chris@49: /** Chris@49: * Return the given element. Chris@49: */ Chris@49: inline arma_hot arma_warn_unused SpValProxy > get_value(const uword i); Chris@49: inline arma_hot arma_warn_unused eT get_value(const uword i) const; Chris@49: Chris@49: inline arma_hot arma_warn_unused SpValProxy > get_value(const uword in_row, const uword in_col); Chris@49: inline arma_hot arma_warn_unused eT get_value(const uword in_row, const uword in_col) const; Chris@49: Chris@49: /** Chris@49: * Given the index representing which of the nonzero values this is, return Chris@49: * its actual location, either in row/col or just the index. Chris@49: */ Chris@49: arma_inline arma_hot arma_warn_unused uword get_position(const uword i) const; Chris@49: arma_inline arma_hot void get_position(const uword i, uword& row_of_i, uword& col_of_i) const; Chris@49: Chris@49: /** Chris@49: * Add an element at the given position, and return a reference to it. The Chris@49: * element will be set to 0 (unless otherwise specified). If the element Chris@49: * already exists, its value will be overwritten. Chris@49: * Chris@49: * @param in_row Row of new element. Chris@49: * @param in_col Column of new element. Chris@49: * @param in_val Value to set new element to (default 0.0). Chris@49: */ Chris@49: inline arma_hot arma_warn_unused eT& add_element(const uword in_row, const uword in_col, const eT in_val = 0.0); Chris@49: Chris@49: /** Chris@49: * Delete an element at the given position. Chris@49: * Chris@49: * @param in_row Row of element to be deleted. Chris@49: * @param in_col Column of element to be deleted. Chris@49: */ Chris@49: inline arma_hot void delete_element(const uword in_row, const uword in_col); Chris@49: Chris@49: Chris@49: public: Chris@49: Chris@49: #ifdef ARMA_EXTRA_SPMAT_PROTO Chris@49: #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPMAT_PROTO) Chris@49: #endif Chris@49: }; Chris@49: Chris@49: Chris@49: Chris@49: #define ARMA_HAS_SPMAT Chris@49: Chris@49: Chris@49: Chris@49: //! @}