"Fossies" - the Fresh Open Source Software Archive

Member "armadillo-9.800.3/include/armadillo_bits/SpMat_bones.hpp" (16 Jun 2016, 34828 Bytes) of package /linux/misc/armadillo-9.800.3.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "SpMat_bones.hpp" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.600.4_vs_9.600.5.

    1 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
    2 // Copyright 2008-2016 National ICT Australia (NICTA)
    3 // 
    4 // Licensed under the Apache License, Version 2.0 (the "License");
    5 // you may not use this file except in compliance with the License.
    6 // You may obtain a copy of the License at
    7 // http://www.apache.org/licenses/LICENSE-2.0
    8 // 
    9 // Unless required by applicable law or agreed to in writing, software
   10 // distributed under the License is distributed on an "AS IS" BASIS,
   11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12 // See the License for the specific language governing permissions and
   13 // limitations under the License.
   14 // ------------------------------------------------------------------------
   15 
   16 
   17 //! \addtogroup SpMat
   18 //! @{
   19 
   20 
   21 //! Sparse matrix class, with data stored in compressed sparse column (CSC) format
   22 template<typename eT>
   23 class SpMat : public SpBase< eT, SpMat<eT> >
   24   {
   25   public:
   26   
   27   typedef eT                                elem_type;  //!< the type of elements stored in the matrix
   28   typedef typename get_pod_type<eT>::result  pod_type;  //!< if eT is std::complex<T>, pod_type is T; otherwise pod_type is eT
   29   
   30   static const bool is_row  = false;
   31   static const bool is_col  = false;
   32   static const bool is_xvec = false;
   33   
   34   const uword n_rows;    //!< number of rows             (read-only)
   35   const uword n_cols;    //!< number of columns          (read-only)
   36   const uword n_elem;    //!< number of elements         (read-only)
   37   const uword n_nonzero; //!< number of nonzero elements (read-only)
   38   const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector
   39   
   40   
   41   // The memory used to store the values of the matrix.
   42   // In accordance with the CSC format, this stores only the actual values.
   43   // The correct locations of the values are assembled from the row indices and column pointers.
   44   // 
   45   // The length of this array is (n_nonzero + 1).
   46   // The final value values[n_nonzero] must be zero to ensure integrity of iterators.
   47   // Use mem_resize(new_n_nonzero) to resize this array.
   48   // 
   49   // WARNING: the 'values' array is only valid after sync() is called;
   50   // WARNING: there is a separate cache for fast element insertion
   51   
   52   arma_aligned const eT* const values;
   53   
   54   
   55   // The row indices of each value.  row_indices[i] is the row of values[i].
   56   // 
   57   // The length of this array is (n_nonzero + 1).
   58   // The final value row_indices[n_nonzero] must be zero to ensure integrity of iterators.
   59   // Use mem_resize(new_n_nonzero) to resize this array.
   60   // 
   61   // WARNING: the 'row_indices' array is only valid after sync() is called;
   62   // WARNING: there is a separate cache for fast element insertion
   63   
   64   arma_aligned const uword* const row_indices;
   65   
   66   
   67   // The column pointers.  This stores the index of the first item in column i.
   68   // That is, values[col_ptrs[i]] is the first value in column i,
   69   // and it is in the row indicated by row_indices[col_ptrs[i]].
   70   // 
   71   // The length of this array is (n_cols + 2).
   72   // The element col_ptrs[n_cols] must be equal to n_nonzero.
   73   // The element col_ptrs[n_cols + 1] must be an invalid very large value to ensure integrity of iterators.
   74   // 
   75   // The col_ptrs array is set by the init() function
   76   // (which is called by constructors, set_size() and other functions that change the matrix size).
   77   // 
   78   // WARNING: the 'col_ptrs' array is only valid after sync() is called;
   79   // WARNING: there is a separate cache for fast element insertion
   80   
   81   arma_aligned const uword* const col_ptrs;
   82   
   83   inline  SpMat();
   84   inline ~SpMat();
   85   
   86   inline explicit SpMat(const uword in_rows, const uword in_cols);
   87   inline explicit SpMat(const SizeMat& s);
   88   
   89   inline            SpMat(const char*        text);
   90   inline SpMat& operator=(const char*        text);
   91   inline            SpMat(const std::string& text);
   92   inline SpMat& operator=(const std::string& text);
   93   inline            SpMat(const SpMat<eT>&   x);
   94   
   95   #if defined(ARMA_USE_CXX11)
   96   inline            SpMat(SpMat&& m);
   97   inline SpMat& operator=(SpMat&& m);
   98   #endif
   99   
  100   inline explicit    SpMat(const MapMat<eT>& x);
  101   inline SpMat&  operator=(const MapMat<eT>& x);
  102   
  103   template<typename T1, typename T2, typename T3>
  104   inline SpMat(const Base<uword,T1>& rowind, const Base<uword,T2>& colptr, const Base<eT,T3>& values, const uword n_rows, const uword n_cols);
  105   
  106   template<typename T1, typename T2>
  107   inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values, const bool sort_locations = true);
  108   
  109   template<typename T1, typename T2>
  110   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, const bool check_for_zeros = true);
  111   
  112   template<typename T1, typename T2>
  113   inline SpMat(const bool add_values, const Base<uword,T1>& locations, const Base<eT,T2>& values, const uword n_rows, const uword n_cols, const bool sort_locations = true, const bool check_for_zeros = true);
  114   
  115   inline SpMat&  operator=(const eT val); //! sets size to 1x1
  116   inline SpMat& operator*=(const eT val);
  117   inline SpMat& operator/=(const eT val);
  118   // operator+=(val) and operator-=(val) are not defined as they don't make sense for sparse matrices
  119   
  120   inline SpMat&  operator=(const SpMat& m);
  121   inline SpMat& operator+=(const SpMat& m);
  122   inline SpMat& operator-=(const SpMat& m);
  123   inline SpMat& operator*=(const SpMat& m);
  124   inline SpMat& operator%=(const SpMat& m);
  125   inline SpMat& operator/=(const SpMat& m);
  126   
  127   template<typename T1> inline explicit    SpMat(const Base<eT, T1>& m);
  128   template<typename T1> inline SpMat&  operator=(const Base<eT, T1>& m);
  129   template<typename T1> inline SpMat& operator+=(const Base<eT, T1>& m);
  130   template<typename T1> inline SpMat& operator-=(const Base<eT, T1>& m);
  131   template<typename T1> inline SpMat& operator*=(const Base<eT, T1>& m);
  132   template<typename T1> inline SpMat& operator/=(const Base<eT, T1>& m);
  133   template<typename T1> inline SpMat& operator%=(const Base<eT, T1>& m);
  134   
  135   template<typename T1> inline explicit    SpMat(const Op<T1, op_diagmat>& expr);
  136   template<typename T1> inline SpMat&  operator=(const Op<T1, op_diagmat>& expr);
  137   template<typename T1> inline SpMat& operator+=(const Op<T1, op_diagmat>& expr);
  138   template<typename T1> inline SpMat& operator-=(const Op<T1, op_diagmat>& expr);
  139   template<typename T1> inline SpMat& operator*=(const Op<T1, op_diagmat>& expr);
  140   template<typename T1> inline SpMat& operator/=(const Op<T1, op_diagmat>& expr);
  141   template<typename T1> inline SpMat& operator%=(const Op<T1, op_diagmat>& expr);
  142 
  143   //! explicit specification of sparse +/- scalar
  144   template<typename T1, typename op_type> inline explicit SpMat(const SpToDOp<T1, op_type>& expr);
  145   
  146   //! construction of complex matrix out of two non-complex matrices
  147   template<typename T1, typename T2>
  148   inline explicit SpMat(const SpBase<pod_type, T1>& A, const SpBase<pod_type, T2>& B);
  149   
  150   inline             SpMat(const SpSubview<eT>& X);
  151   inline SpMat&  operator=(const SpSubview<eT>& X);
  152   inline SpMat& operator+=(const SpSubview<eT>& X);
  153   inline SpMat& operator-=(const SpSubview<eT>& X);
  154   inline SpMat& operator*=(const SpSubview<eT>& X);
  155   inline SpMat& operator%=(const SpSubview<eT>& X);
  156   inline SpMat& operator/=(const SpSubview<eT>& X);
  157   
  158   inline             SpMat(const spdiagview<eT>& X);
  159   inline SpMat&  operator=(const spdiagview<eT>& X);
  160   inline SpMat& operator+=(const spdiagview<eT>& X);
  161   inline SpMat& operator-=(const spdiagview<eT>& X);
  162   inline SpMat& operator*=(const spdiagview<eT>& X);
  163   inline SpMat& operator%=(const spdiagview<eT>& X);
  164   inline SpMat& operator/=(const spdiagview<eT>& X);
  165   
  166   // delayed unary ops
  167   template<typename T1, typename spop_type> inline             SpMat(const SpOp<T1, spop_type>& X);
  168   template<typename T1, typename spop_type> inline SpMat&  operator=(const SpOp<T1, spop_type>& X);
  169   template<typename T1, typename spop_type> inline SpMat& operator+=(const SpOp<T1, spop_type>& X);
  170   template<typename T1, typename spop_type> inline SpMat& operator-=(const SpOp<T1, spop_type>& X);
  171   template<typename T1, typename spop_type> inline SpMat& operator*=(const SpOp<T1, spop_type>& X);
  172   template<typename T1, typename spop_type> inline SpMat& operator%=(const SpOp<T1, spop_type>& X);
  173   template<typename T1, typename spop_type> inline SpMat& operator/=(const SpOp<T1, spop_type>& X);
  174   
  175   // delayed binary ops
  176   template<typename T1, typename T2, typename spglue_type> inline             SpMat(const SpGlue<T1, T2, spglue_type>& X);
  177   template<typename T1, typename T2, typename spglue_type> inline SpMat&  operator=(const SpGlue<T1, T2, spglue_type>& X);
  178   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator+=(const SpGlue<T1, T2, spglue_type>& X);
  179   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator-=(const SpGlue<T1, T2, spglue_type>& X);
  180   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator*=(const SpGlue<T1, T2, spglue_type>& X);
  181   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator%=(const SpGlue<T1, T2, spglue_type>& X);
  182   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator/=(const SpGlue<T1, T2, spglue_type>& X);
  183   
  184   // delayed mixed-type unary ops
  185   template<typename T1, typename spop_type> inline             SpMat(const mtSpOp<eT, T1, spop_type>& X);
  186   template<typename T1, typename spop_type> inline SpMat&  operator=(const mtSpOp<eT, T1, spop_type>& X);
  187   template<typename T1, typename spop_type> inline SpMat& operator+=(const mtSpOp<eT, T1, spop_type>& X);
  188   template<typename T1, typename spop_type> inline SpMat& operator-=(const mtSpOp<eT, T1, spop_type>& X);
  189   template<typename T1, typename spop_type> inline SpMat& operator*=(const mtSpOp<eT, T1, spop_type>& X);
  190   template<typename T1, typename spop_type> inline SpMat& operator%=(const mtSpOp<eT, T1, spop_type>& X);
  191   template<typename T1, typename spop_type> inline SpMat& operator/=(const mtSpOp<eT, T1, spop_type>& X);
  192   
  193   // delayed mixed-type binary ops
  194   template<typename T1, typename T2, typename spglue_type> inline             SpMat(const mtSpGlue<eT, T1, T2, spglue_type>& X);
  195   template<typename T1, typename T2, typename spglue_type> inline SpMat&  operator=(const mtSpGlue<eT, T1, T2, spglue_type>& X);
  196   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator+=(const mtSpGlue<eT, T1, T2, spglue_type>& X);
  197   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator-=(const mtSpGlue<eT, T1, T2, spglue_type>& X);
  198   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator*=(const mtSpGlue<eT, T1, T2, spglue_type>& X);
  199   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator%=(const mtSpGlue<eT, T1, T2, spglue_type>& X);
  200   template<typename T1, typename T2, typename spglue_type> inline SpMat& operator/=(const mtSpGlue<eT, T1, T2, spglue_type>& X);
  201   
  202   
  203   arma_inline       SpSubview<eT> row(const uword row_num);
  204   arma_inline const SpSubview<eT> row(const uword row_num) const;
  205   
  206   inline            SpSubview<eT> operator()(const uword row_num, const span& col_span);
  207   inline      const SpSubview<eT> operator()(const uword row_num, const span& col_span) const;
  208   
  209   arma_inline       SpSubview<eT> col(const uword col_num);
  210   arma_inline const SpSubview<eT> col(const uword col_num) const;
  211   
  212   inline            SpSubview<eT> operator()(const span& row_span, const uword col_num);
  213   inline      const SpSubview<eT> operator()(const span& row_span, const uword col_num) const;
  214   
  215   arma_inline       SpSubview<eT> rows(const uword in_row1, const uword in_row2);
  216   arma_inline const SpSubview<eT> rows(const uword in_row1, const uword in_row2) const;
  217   
  218   arma_inline       SpSubview<eT> cols(const uword in_col1, const uword in_col2);
  219   arma_inline const SpSubview<eT> cols(const uword in_col1, const uword in_col2) const;
  220   
  221   arma_inline       SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
  222   arma_inline const SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
  223   
  224   arma_inline       SpSubview<eT> submat(const uword in_row1, const uword in_col1, const SizeMat& s);
  225   arma_inline const SpSubview<eT> submat(const uword in_row1, const uword in_col1, const SizeMat& s) const;
  226   
  227   inline            SpSubview<eT> submat    (const span& row_span, const span& col_span);
  228   inline      const SpSubview<eT> submat    (const span& row_span, const span& col_span) const;
  229   
  230   inline            SpSubview<eT> operator()(const span& row_span, const span& col_span);
  231   inline      const SpSubview<eT> operator()(const span& row_span, const span& col_span) const;
  232   
  233   arma_inline       SpSubview<eT> operator()(const uword in_row1, const uword in_col1, const SizeMat& s);
  234   arma_inline const SpSubview<eT> operator()(const uword in_row1, const uword in_col1, const SizeMat& s) const;
  235   
  236   
  237   inline       SpSubview<eT> head_rows(const uword N);
  238   inline const SpSubview<eT> head_rows(const uword N) const;
  239   
  240   inline       SpSubview<eT> tail_rows(const uword N);
  241   inline const SpSubview<eT> tail_rows(const uword N) const;
  242   
  243   inline       SpSubview<eT> head_cols(const uword N);
  244   inline const SpSubview<eT> head_cols(const uword N) const;
  245   
  246   inline       SpSubview<eT> tail_cols(const uword N);
  247   inline const SpSubview<eT> tail_cols(const uword N) const;
  248   
  249   
  250   inline       spdiagview<eT> diag(const sword in_id = 0);
  251   inline const spdiagview<eT> diag(const sword in_id = 0) const;
  252   
  253   
  254   inline void swap_rows(const uword in_row1, const uword in_row2);
  255   inline void swap_cols(const uword in_col1, const uword in_col2);
  256   
  257   inline void shed_row(const uword row_num);
  258   inline void shed_col(const uword col_num);
  259   
  260   inline void shed_rows(const uword in_row1, const uword in_row2);
  261   inline void shed_cols(const uword in_col1, const uword in_col2);
  262   
  263   
  264   // access the i-th element; if there is nothing at element i, 0 is returned
  265   arma_inline arma_warn_unused SpMat_MapMat_val<eT> operator[] (const uword i);
  266   arma_inline arma_warn_unused eT                   operator[] (const uword i) const;
  267   arma_inline arma_warn_unused SpMat_MapMat_val<eT> at         (const uword i);
  268   arma_inline arma_warn_unused eT                   at         (const uword i) const;
  269   arma_inline arma_warn_unused SpMat_MapMat_val<eT> operator() (const uword i);
  270   arma_inline arma_warn_unused eT                   operator() (const uword i) const;
  271   
  272   // access the element at the given row and column; if there is nothing at that position, 0 is returned
  273   arma_inline arma_warn_unused SpMat_MapMat_val<eT> at         (const uword in_row, const uword in_col);
  274   arma_inline arma_warn_unused eT                   at         (const uword in_row, const uword in_col) const;
  275   arma_inline arma_warn_unused SpMat_MapMat_val<eT> operator() (const uword in_row, const uword in_col);
  276   arma_inline arma_warn_unused eT                   operator() (const uword in_row, const uword in_col) const;
  277   
  278   
  279   arma_inline arma_warn_unused bool is_empty()  const;
  280   arma_inline arma_warn_unused bool is_vec()    const;
  281   arma_inline arma_warn_unused bool is_rowvec() const;
  282   arma_inline arma_warn_unused bool is_colvec() const;
  283   arma_inline arma_warn_unused bool is_square() const;
  284        inline arma_warn_unused bool is_finite() const;
  285   
  286   inline arma_warn_unused bool is_symmetric() const;
  287   inline arma_warn_unused bool is_symmetric(const typename get_pod_type<eT>::result tol) const;
  288   
  289   inline arma_warn_unused bool is_hermitian() const;
  290   inline arma_warn_unused bool is_hermitian(const typename get_pod_type<eT>::result tol) const;
  291   
  292   inline arma_warn_unused bool has_inf() const;
  293   inline arma_warn_unused bool has_nan() const;
  294   
  295   arma_inline arma_warn_unused bool in_range(const uword i) const;
  296   arma_inline arma_warn_unused bool in_range(const span& x) const;
  297   
  298   arma_inline arma_warn_unused bool in_range(const uword   in_row, const uword   in_col) const;
  299   arma_inline arma_warn_unused bool in_range(const span& row_span, const uword   in_col) const;
  300   arma_inline arma_warn_unused bool in_range(const uword   in_row, const span& col_span) const;
  301   arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const;
  302   
  303   arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const;
  304   
  305   
  306   arma_cold inline void impl_print(                           const std::string& extra_text) const;
  307   arma_cold inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const;
  308   
  309   arma_cold inline void impl_raw_print(                           const std::string& extra_text) const;
  310   arma_cold inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const;
  311   
  312   arma_cold inline void impl_print_dense(                           const std::string& extra_text) const;
  313   arma_cold inline void impl_print_dense(std::ostream& user_stream, const std::string& extra_text) const;
  314   
  315   arma_cold inline void impl_raw_print_dense(                           const std::string& extra_text) const;
  316   arma_cold inline void impl_raw_print_dense(std::ostream& user_stream, const std::string& extra_text) const;
  317   
  318   
  319   template<typename eT2> inline void copy_size(const SpMat<eT2>& m);
  320   template<typename eT2> inline void copy_size(const   Mat<eT2>& m);
  321   
  322   inline void set_size(const uword in_elem);
  323   inline void set_size(const uword in_rows, const uword in_cols);
  324   inline void set_size(const SizeMat& s);
  325   
  326   inline void   resize(const uword in_rows, const uword in_cols);
  327   inline void   resize(const SizeMat& s);
  328   
  329   inline void  reshape(const uword in_rows, const uword in_cols);
  330   inline void  reshape(const SizeMat& s);
  331   
  332   inline void  reshape_helper_generic(const uword in_rows, const uword in_cols);  //! internal use only
  333   inline void  reshape_helper_intovec();                                          //! internal use only
  334   
  335   arma_deprecated inline void reshape(const uword in_rows, const uword in_cols, const uword dim);  //!< NOTE: don't use this form: it will be removed
  336   
  337   template<typename functor> inline const SpMat&  for_each(functor F);
  338   template<typename functor> inline const SpMat&  for_each(functor F) const;
  339   
  340   template<typename functor> inline const SpMat& transform(functor F);
  341   
  342   inline const SpMat& replace(const eT old_val, const eT new_val);
  343   
  344   inline const SpMat& clean(const pod_type threshold);
  345   
  346   inline const SpMat& zeros();
  347   inline const SpMat& zeros(const uword in_elem);
  348   inline const SpMat& zeros(const uword in_rows, const uword in_cols);
  349   inline const SpMat& zeros(const SizeMat& s);
  350   
  351   inline const SpMat& eye();
  352   inline const SpMat& eye(const uword in_rows, const uword in_cols);
  353   inline const SpMat& eye(const SizeMat& s);
  354   
  355   inline const SpMat& speye();
  356   inline const SpMat& speye(const uword in_rows, const uword in_cols);
  357   inline const SpMat& speye(const SizeMat& s);
  358   
  359   inline const SpMat& sprandu(const uword in_rows, const uword in_cols, const double density);
  360   inline const SpMat& sprandu(const SizeMat& s,                         const double density);
  361   
  362   inline const SpMat& sprandn(const uword in_rows, const uword in_cols, const double density);
  363   inline const SpMat& sprandn(const SizeMat& s,                         const double density);
  364   
  365   inline void reset();
  366   
  367   //! don't use this unless you're writing internal Armadillo code
  368   inline void reserve(const uword in_rows, const uword in_cols, const uword new_n_nonzero);
  369   
  370   //! don't use this unless you're writing internal Armadillo code
  371   inline SpMat(const arma_reserve_indicator&, const uword in_rows, const uword in_cols, const uword new_n_nonzero);
  372   
  373   //! don't use this unless you're writing internal Armadillo code
  374   template<typename eT2>
  375   inline SpMat(const arma_layout_indicator&, const SpMat<eT2>& x);
  376   
  377   template<typename T1> inline void set_real(const SpBase<pod_type,T1>& X);
  378   template<typename T1> inline void set_imag(const SpBase<pod_type,T1>& X);
  379   
  380   
  381   // saving and loading
  382   // TODO: implement auto_detect for sparse matrices
  383   
  384   inline arma_cold bool save(const std::string   name, const file_type type = arma_binary, const bool print_status = true) const;
  385   inline arma_cold bool save(      std::ostream& os,   const file_type type = arma_binary, const bool print_status = true) const;
  386   
  387   inline arma_cold bool load(const std::string   name, const file_type type = arma_binary, const bool print_status = true);
  388   inline arma_cold bool load(      std::istream& is,   const file_type type = arma_binary, const bool print_status = true);
  389   
  390   inline arma_cold bool quiet_save(const std::string   name, const file_type type = arma_binary) const;
  391   inline arma_cold bool quiet_save(      std::ostream& os,   const file_type type = arma_binary) const;
  392   
  393   inline arma_cold bool quiet_load(const std::string   name, const file_type type = arma_binary);
  394   inline arma_cold bool quiet_load(      std::istream& is,   const file_type type = arma_binary);
  395   
  396   
  397   
  398   // necessary forward declarations
  399   class iterator_base;
  400   class iterator;
  401   class const_iterator;
  402   class row_iterator;
  403   class const_row_iterator;
  404   
  405   // iterator_base provides basic operators but not how to compare or how to iterate
  406   class iterator_base
  407     {
  408     public:
  409     
  410     inline iterator_base();
  411     inline iterator_base(const SpMat& in_M);
  412     inline iterator_base(const SpMat& in_M, const uword col, const uword pos);
  413     
  414     arma_inline eT operator*() const;
  415     
  416     // don't hold location internally; call "dummy" methods to get that information
  417     arma_inline uword row() const { return M->row_indices[internal_pos]; }
  418     arma_inline uword col() const { return internal_col;                 }
  419     arma_inline uword pos() const { return internal_pos;                 }
  420     
  421     arma_aligned const SpMat* M;
  422     arma_aligned       uword  internal_col;
  423     arma_aligned       uword  internal_pos;
  424     
  425     typedef std::bidirectional_iterator_tag iterator_category;
  426     typedef eT                              value_type;
  427     typedef std::ptrdiff_t                  difference_type;  // TODO: not certain on this one
  428     typedef const eT*                       pointer;
  429     typedef const eT&                       reference;
  430     };
  431   
  432   class const_iterator : public iterator_base
  433     {
  434     public:
  435     
  436     inline const_iterator();
  437     inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // assumes initial_pos is valid
  438     //! once initialised, will be at the first nonzero value after the given position (using forward columnwise traversal)
  439     inline const_iterator(const SpMat& in_M, uword in_row, uword in_col);
  440     //! if you know the exact position of the iterator;  in_row is a dummy argument
  441     inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uword in_pos);
  442     inline const_iterator(const const_iterator& other);
  443     
  444     inline arma_hot         const_iterator& operator++();
  445     inline arma_warn_unused const_iterator  operator++(int);
  446     
  447     inline arma_hot         const_iterator& operator--();
  448     inline arma_warn_unused const_iterator  operator--(int);
  449     
  450     inline arma_hot bool operator==(const const_iterator& rhs) const;
  451     inline arma_hot bool operator!=(const const_iterator& rhs) const;
  452     
  453     inline arma_hot bool operator==(const typename SpSubview<eT>::const_iterator& rhs) const;
  454     inline arma_hot bool operator!=(const typename SpSubview<eT>::const_iterator& rhs) const;
  455     
  456     inline arma_hot bool operator==(const const_row_iterator& rhs) const;
  457     inline arma_hot bool operator!=(const const_row_iterator& rhs) const;
  458     
  459     inline arma_hot bool operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const;
  460     inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const;
  461     };
  462   
  463   /**
  464    * So that we can iterate over nonzero values, we need an iterator implementation.
  465    * This can't be as simple as for Mat, which is just a pointer to an eT.
  466    * If a value is set to 0 using this iterator, the iterator is no longer valid!
  467    */
  468   class iterator : public const_iterator
  469     {
  470     public:
  471     
  472     inline iterator() : const_iterator() { }
  473     inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in_M, initial_pos) { }
  474     inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterator(in_M, in_row, in_col) { }
  475     inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos) : const_iterator(in_M, in_row, in_col, in_pos) { }
  476     inline iterator(const iterator& other) : const_iterator(other) { }
  477     
  478     inline arma_hot SpValProxy<SpMat<eT> > operator*();
  479     
  480     // overloads needed for return type correctness
  481     inline arma_hot         iterator& operator++();
  482     inline arma_warn_unused iterator  operator++(int);
  483     
  484     inline arma_hot         iterator& operator--();
  485     inline arma_warn_unused iterator  operator--(int);
  486     
  487     // this has a different value_type than iterator_base
  488     typedef SpValProxy<SpMat<eT> >         value_type;
  489     typedef const SpValProxy<SpMat<eT> >*  pointer;
  490     typedef const SpValProxy<SpMat<eT> >&  reference;
  491     };
  492   
  493   class const_row_iterator : public iterator_base
  494     {
  495     public:
  496     
  497     inline const_row_iterator();
  498     inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0);
  499     //! once initialised, will be at the first nonzero value after the given position (using forward row-wise traversal)
  500     inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col);
  501     inline const_row_iterator(const const_row_iterator& other);
  502     
  503     inline arma_hot         const_row_iterator& operator++();
  504     inline arma_warn_unused const_row_iterator  operator++(int);
  505     
  506     inline arma_hot         const_row_iterator& operator--();
  507     inline arma_warn_unused const_row_iterator  operator--(int);
  508     
  509     uword internal_row; // hold row internally
  510     uword actual_pos; // this holds the true position we are at in the matrix, as column-major indexing
  511     
  512     arma_inline eT operator*() const { return iterator_base::M->values[actual_pos]; }
  513     
  514     arma_inline uword row() const { return internal_row; }
  515     
  516     inline arma_hot bool operator==(const const_iterator& rhs) const;
  517     inline arma_hot bool operator!=(const const_iterator& rhs) const;
  518     
  519     inline arma_hot bool operator==(const typename SpSubview<eT>::const_iterator& rhs) const;
  520     inline arma_hot bool operator!=(const typename SpSubview<eT>::const_iterator& rhs) const;
  521     
  522     inline arma_hot bool operator==(const const_row_iterator& rhs) const;
  523     inline arma_hot bool operator!=(const const_row_iterator& rhs) const;
  524     
  525     inline arma_hot bool operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const;
  526     inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const;
  527     };
  528   
  529   class row_iterator : public const_row_iterator
  530     {
  531     public:
  532     
  533     inline row_iterator() : const_row_iterator() {}
  534     inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { }
  535     //! once initialised, will be at the first nonzero value after the given position (using forward row-wise traversal)
  536     inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { }
  537     inline row_iterator(const row_iterator& other) : const_row_iterator(other) { }
  538     
  539     inline arma_hot SpValProxy<SpMat<eT> > operator*();
  540     
  541     // overloads required for return type correctness
  542     inline arma_hot         row_iterator& operator++();
  543     inline arma_warn_unused row_iterator  operator++(int);
  544     
  545     inline arma_hot         row_iterator& operator--();
  546     inline arma_warn_unused row_iterator  operator--(int);
  547     
  548     // this has a different value_type than iterator_base
  549     typedef SpValProxy<SpMat<eT> >         value_type;
  550     typedef const SpValProxy<SpMat<eT> >*  pointer;
  551     typedef const SpValProxy<SpMat<eT> >&  reference;
  552     };
  553   
  554   
  555   typedef       iterator       col_iterator;
  556   typedef const_iterator const_col_iterator;
  557   
  558   typedef       iterator       row_col_iterator;
  559   typedef const_iterator const_row_col_iterator;
  560   
  561   
  562   inline       iterator     begin();
  563   inline const_iterator     begin() const;
  564   inline const_iterator    cbegin() const;
  565   
  566   inline       iterator     end();
  567   inline const_iterator     end() const;
  568   inline const_iterator    cend() const;
  569   
  570   inline       col_iterator begin_col(const uword col_num);
  571   inline const_col_iterator begin_col(const uword col_num) const;
  572   
  573   inline       col_iterator begin_col_no_sync(const uword col_num);
  574   inline const_col_iterator begin_col_no_sync(const uword col_num) const;
  575   
  576   inline       col_iterator end_col(const uword col_num);
  577   inline const_col_iterator end_col(const uword col_num) const;
  578   
  579   inline       col_iterator end_col_no_sync(const uword col_num);
  580   inline const_col_iterator end_col_no_sync(const uword col_num) const;
  581   
  582   inline       row_iterator begin_row(const uword row_num = 0);
  583   inline const_row_iterator begin_row(const uword row_num = 0) const;
  584   
  585   inline       row_iterator end_row();
  586   inline const_row_iterator end_row() const;
  587   
  588   inline       row_iterator end_row(const uword row_num);
  589   inline const_row_iterator end_row(const uword row_num) const;
  590   
  591   inline       row_col_iterator begin_row_col();
  592   inline const_row_col_iterator begin_row_col() const;
  593   
  594   inline       row_col_iterator end_row_col();
  595   inline const_row_col_iterator end_row_col() const;
  596   
  597   
  598   inline void  clear();
  599   inline bool  empty() const;
  600   inline uword size()  const;
  601   
  602   // Resize memory.
  603   // If the new size is larger, the column pointers and new memory still need to be correctly set.
  604   // If the new size is smaller, the first new_n_nonzero elements will be copied.
  605   // n_nonzero is updated.
  606   inline void mem_resize(const uword new_n_nonzero);
  607   
  608   //! synchronise CSC from cache
  609   inline void sync() const;
  610   
  611   //! don't use this unless you're writing internal Armadillo code
  612   inline void remove_zeros();
  613   
  614   //! don't use this unless you're writing internal Armadillo code
  615   inline void steal_mem(SpMat& X);
  616   
  617   //! don't use this unless you're writing internal Armadillo code
  618   inline void steal_mem_simple(SpMat& X);
  619   
  620   //! don't use this unless you're writing internal Armadillo code
  621   template<              typename T1, typename Functor> arma_hot inline void init_xform   (const SpBase<eT, T1>& x, const Functor& func);
  622   template<typename eT2, typename T1, typename Functor> arma_hot inline void init_xform_mt(const SpBase<eT2,T1>& x, const Functor& func);
  623   
  624   //! don't use this unless you're writing internal Armadillo code
  625   arma_inline bool is_alias(const SpMat<eT>& X) const;
  626   
  627   
  628   protected:
  629   
  630   inline void                init(uword in_rows, uword in_cols, const uword new_n_nonzero = 0);
  631   inline void arma_cold init_cold(uword in_rows, uword in_cols, const uword new_n_nonzero = 0);
  632   
  633   inline void init(const std::string& text);
  634   inline void init(const  SpMat<eT>& x);
  635   inline void init(const MapMat<eT>& x);
  636   
  637   inline void init_simple(const SpMat<eT>& x);
  638   
  639   inline void init_batch_std(const Mat<uword>& locations, const Mat<eT>& values, const bool sort_locations);
  640   inline void init_batch_add(const Mat<uword>& locations, const Mat<eT>& values, const bool sort_locations);
  641   
  642   inline SpMat(const arma_vec_indicator&, const uword in_vec_state);
  643   inline SpMat(const arma_vec_indicator&, const uword in_n_rows, const uword in_n_cols, const uword in_vec_state);
  644   
  645   
  646   private:
  647   
  648   inline arma_hot arma_warn_unused const eT* find_value_csc(const uword in_row, const uword in_col) const;
  649   
  650   inline arma_hot arma_warn_unused eT get_value(const uword i                         ) const;
  651   inline arma_hot arma_warn_unused eT get_value(const uword in_row, const uword in_col) const;
  652   
  653   inline arma_hot arma_warn_unused eT get_value_csc(const uword i                         ) const;
  654   inline arma_hot arma_warn_unused eT get_value_csc(const uword in_row, const uword in_col) const;
  655   
  656   inline arma_hot arma_warn_unused bool try_set_value_csc(const uword in_row, const uword in_col, const eT in_val);
  657   inline arma_hot arma_warn_unused bool try_add_value_csc(const uword in_row, const uword in_col, const eT in_val);
  658   inline arma_hot arma_warn_unused bool try_sub_value_csc(const uword in_row, const uword in_col, const eT in_val);
  659   inline arma_hot arma_warn_unused bool try_mul_value_csc(const uword in_row, const uword in_col, const eT in_val);
  660   inline arma_hot arma_warn_unused bool try_div_value_csc(const uword in_row, const uword in_col, const eT in_val);
  661   
  662   inline arma_warn_unused eT&  insert_element(const uword in_row, const uword in_col, const eT in_val = eT(0));
  663   inline                  void delete_element(const uword in_row, const uword in_col);
  664   
  665   
  666   // cache related
  667   
  668   arma_aligned mutable MapMat<eT> cache;
  669   arma_aligned mutable state_type sync_state;
  670   // 0: cache needs to be updated from CSC (ie.   CSC has more recent data)
  671   // 1: CSC needs to be updated from cache (ie. cache has more recent data)
  672   // 2: no update required                 (ie. CSC and cache contain the same data)
  673   
  674   #if defined(ARMA_USE_CXX11)
  675   arma_aligned mutable std::mutex cache_mutex;
  676   #endif
  677   
  678   arma_inline void invalidate_cache() const;
  679   arma_inline void invalidate_csc()   const;
  680   
  681   inline void sync_cache()        const;
  682   inline void sync_cache_simple() const;
  683   inline void sync_csc()          const;
  684   inline void sync_csc_simple()   const;
  685   
  686   
  687   friend class SpValProxy< SpMat<eT> >;  // allow SpValProxy to call insert_element() and delete_element()
  688   friend class SpSubview<eT>;
  689   friend class SpRow<eT>;
  690   friend class SpCol<eT>;
  691   friend class SpMat_MapMat_val<eT>;
  692   friend class SpSubview_MapMat_val<eT>;
  693   friend class spdiagview<eT>;
  694   
  695   
  696   public:
  697   
  698   #ifdef ARMA_EXTRA_SPMAT_PROTO
  699     #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPMAT_PROTO)
  700   #endif
  701   };
  702 
  703 
  704 
  705 class SpMat_aux
  706   {
  707   public:
  708   
  709   template<typename eT, typename T1> inline static void set_real(SpMat<eT>&                out, const SpBase<eT,T1>& X);
  710   template<typename T,  typename T1> inline static void set_real(SpMat< std::complex<T> >& out, const SpBase< T,T1>& X);
  711   
  712   template<typename eT, typename T1> inline static void set_imag(SpMat<eT>&                out, const SpBase<eT,T1>& X);
  713   template<typename T,  typename T1> inline static void set_imag(SpMat< std::complex<T> >& out, const SpBase< T,T1>& X);
  714   };
  715 
  716 
  717 
  718 #define ARMA_HAS_SPMAT
  719 
  720 
  721 
  722 //! @}