SpSubview_bones.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  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. //! \addtogroup SpSubview
  16. //! @{
  17. template<typename eT>
  18. class SpSubview : public SpBase<eT, SpSubview<eT> >
  19. {
  20. public:
  21. const SpMat<eT>& m;
  22. typedef eT elem_type;
  23. typedef typename get_pod_type<elem_type>::result pod_type;
  24. static const bool is_row = false;
  25. static const bool is_col = false;
  26. static const bool is_xvec = false;
  27. const uword aux_row1;
  28. const uword aux_col1;
  29. const uword n_rows;
  30. const uword n_cols;
  31. const uword n_elem;
  32. const uword n_nonzero;
  33. friend class SpValProxy< SpSubview<eT> >; // allow SpValProxy to call insert_element() and delete_element()
  34. protected:
  35. inline SpSubview(const SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
  36. inline SpSubview( SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols);
  37. public:
  38. inline ~SpSubview();
  39. inline const SpSubview& operator+= (const eT val);
  40. inline const SpSubview& operator-= (const eT val);
  41. inline const SpSubview& operator*= (const eT val);
  42. inline const SpSubview& operator/= (const eT val);
  43. inline const SpSubview& operator=(const SpSubview& x);
  44. template<typename T1> inline const SpSubview& operator= (const Base<eT, T1>& x);
  45. template<typename T1> inline const SpSubview& operator+=(const Base<eT, T1>& x);
  46. template<typename T1> inline const SpSubview& operator-=(const Base<eT, T1>& x);
  47. template<typename T1> inline const SpSubview& operator*=(const Base<eT, T1>& x);
  48. template<typename T1> inline const SpSubview& operator%=(const Base<eT, T1>& x);
  49. template<typename T1> inline const SpSubview& operator/=(const Base<eT, T1>& x);
  50. template<typename T1> inline const SpSubview& operator_equ_common(const SpBase<eT, T1>& x);
  51. template<typename T1> inline const SpSubview& operator= (const SpBase<eT, T1>& x);
  52. template<typename T1> inline const SpSubview& operator+=(const SpBase<eT, T1>& x);
  53. template<typename T1> inline const SpSubview& operator-=(const SpBase<eT, T1>& x);
  54. template<typename T1> inline const SpSubview& operator*=(const SpBase<eT, T1>& x);
  55. template<typename T1> inline const SpSubview& operator%=(const SpBase<eT, T1>& x);
  56. template<typename T1> inline const SpSubview& operator/=(const SpBase<eT, T1>& x);
  57. /*
  58. inline static void extract(SpMat<eT>& out, const SpSubview& in);
  59. inline static void plus_inplace(Mat<eT>& out, const subview& in);
  60. inline static void minus_inplace(Mat<eT>& out, const subview& in);
  61. inline static void schur_inplace(Mat<eT>& out, const subview& in);
  62. inline static void div_inplace(Mat<eT>& out, const subview& in);
  63. */
  64. template<typename functor> inline void for_each(functor F);
  65. template<typename functor> inline void for_each(functor F) const;
  66. template<typename functor> inline void transform(functor F);
  67. inline void replace(const eT old_val, const eT new_val);
  68. inline void clean(const pod_type threshold);
  69. inline void fill(const eT val);
  70. inline void zeros();
  71. inline void ones();
  72. inline void eye();
  73. arma_hot inline SpSubview_MapMat_val<eT> operator[](const uword i);
  74. arma_hot inline eT operator[](const uword i) const;
  75. arma_hot inline SpSubview_MapMat_val<eT> operator()(const uword i);
  76. arma_hot inline eT operator()(const uword i) const;
  77. arma_hot inline SpSubview_MapMat_val<eT> operator()(const uword in_row, const uword in_col);
  78. arma_hot inline eT operator()(const uword in_row, const uword in_col) const;
  79. arma_hot inline SpSubview_MapMat_val<eT> at(const uword i);
  80. arma_hot inline eT at(const uword i) const;
  81. arma_hot inline SpSubview_MapMat_val<eT> at(const uword in_row, const uword in_col);
  82. arma_hot inline eT at(const uword in_row, const uword in_col) const;
  83. inline bool check_overlap(const SpSubview& x) const;
  84. inline bool is_vec() const;
  85. inline SpSubview_row<eT> row(const uword row_num);
  86. inline const SpSubview_row<eT> row(const uword row_num) const;
  87. inline SpSubview_col<eT> col(const uword col_num);
  88. inline const SpSubview_col<eT> col(const uword col_num) const;
  89. inline SpSubview rows(const uword in_row1, const uword in_row2);
  90. inline const SpSubview rows(const uword in_row1, const uword in_row2) const;
  91. inline SpSubview cols(const uword in_col1, const uword in_col2);
  92. inline const SpSubview cols(const uword in_col1, const uword in_col2) const;
  93. inline SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2);
  94. inline const SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const;
  95. inline SpSubview submat(const span& row_span, const span& col_span);
  96. inline const SpSubview submat(const span& row_span, const span& col_span) const;
  97. inline SpSubview operator()(const uword row_num, const span& col_span);
  98. inline const SpSubview operator()(const uword row_num, const span& col_span) const;
  99. inline SpSubview operator()(const span& row_span, const uword col_num);
  100. inline const SpSubview operator()(const span& row_span, const uword col_num) const;
  101. inline SpSubview operator()(const span& row_span, const span& col_span);
  102. inline const SpSubview operator()(const span& row_span, const span& col_span) const;
  103. inline void swap_rows(const uword in_row1, const uword in_row2);
  104. inline void swap_cols(const uword in_col1, const uword in_col2);
  105. // Forward declarations.
  106. class iterator_base;
  107. class const_iterator;
  108. class iterator;
  109. class const_row_iterator;
  110. class row_iterator;
  111. // Similar to SpMat iterators but automatically iterates past and ignores values not in the subview.
  112. class iterator_base
  113. {
  114. public:
  115. inline iterator_base(const SpSubview& in_M);
  116. inline iterator_base(const SpSubview& in_M, const uword col, const uword pos);
  117. arma_inline uword col() const { return internal_col; }
  118. arma_inline uword pos() const { return internal_pos; }
  119. arma_aligned const SpSubview* M;
  120. arma_aligned uword internal_col;
  121. arma_aligned uword internal_pos;
  122. typedef std::bidirectional_iterator_tag iterator_category;
  123. typedef eT value_type;
  124. typedef std::ptrdiff_t difference_type; // TODO: not certain on this one
  125. typedef const eT* pointer;
  126. typedef const eT& reference;
  127. };
  128. class const_iterator : public iterator_base
  129. {
  130. public:
  131. inline const_iterator(const SpSubview& in_M, uword initial_pos = 0);
  132. inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col);
  133. inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col, uword in_pos, uword skip_pos);
  134. inline const_iterator(const const_iterator& other);
  135. arma_inline eT operator*() const;
  136. // Don't hold location internally; call "dummy" methods to get that information.
  137. arma_inline uword row() const { return iterator_base::M->m.row_indices[iterator_base::internal_pos + skip_pos] - iterator_base::M->aux_row1; }
  138. inline arma_hot const_iterator& operator++();
  139. inline arma_warn_unused const_iterator operator++(int);
  140. inline arma_hot const_iterator& operator--();
  141. inline arma_warn_unused const_iterator operator--(int);
  142. inline arma_hot bool operator!=(const const_iterator& rhs) const;
  143. inline arma_hot bool operator==(const const_iterator& rhs) const;
  144. inline arma_hot bool operator!=(const typename SpMat<eT>::const_iterator& rhs) const;
  145. inline arma_hot bool operator==(const typename SpMat<eT>::const_iterator& rhs) const;
  146. inline arma_hot bool operator!=(const const_row_iterator& rhs) const;
  147. inline arma_hot bool operator==(const const_row_iterator& rhs) const;
  148. inline arma_hot bool operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const;
  149. inline arma_hot bool operator==(const typename SpMat<eT>::const_row_iterator& rhs) const;
  150. arma_aligned uword skip_pos; // not used in row_iterator or const_row_iterator
  151. };
  152. class iterator : public const_iterator
  153. {
  154. public:
  155. inline iterator(SpSubview& in_M, const uword initial_pos = 0) : const_iterator(in_M, initial_pos) { }
  156. inline iterator(SpSubview& in_M, const uword in_row, const uword in_col) : const_iterator(in_M, in_row, in_col) { }
  157. inline iterator(SpSubview& in_M, const uword in_row, const uword in_col, const uword in_pos, const uword in_skip_pos) : const_iterator(in_M, in_row, in_col, in_pos, in_skip_pos) { }
  158. inline iterator(const iterator& other) : const_iterator(other) { }
  159. inline arma_hot SpValProxy<SpSubview<eT> > operator*();
  160. // overloads needed for return type correctness
  161. inline arma_hot iterator& operator++();
  162. inline arma_warn_unused iterator operator++(int);
  163. inline arma_hot iterator& operator--();
  164. inline arma_warn_unused iterator operator--(int);
  165. // This has a different value_type than iterator_base.
  166. typedef SpValProxy<SpSubview<eT> > value_type;
  167. typedef const SpValProxy<SpSubview<eT> >* pointer;
  168. typedef const SpValProxy<SpSubview<eT> >& reference;
  169. };
  170. class const_row_iterator : public iterator_base
  171. {
  172. public:
  173. inline const_row_iterator();
  174. inline const_row_iterator(const SpSubview& in_M, uword initial_pos = 0);
  175. inline const_row_iterator(const SpSubview& in_M, uword in_row, uword in_col);
  176. inline const_row_iterator(const const_row_iterator& other);
  177. inline arma_hot const_row_iterator& operator++();
  178. inline arma_warn_unused const_row_iterator operator++(int);
  179. inline arma_hot const_row_iterator& operator--();
  180. inline arma_warn_unused const_row_iterator operator--(int);
  181. uword internal_row; // Hold row internally because we use internal_pos differently.
  182. uword actual_pos; // Actual position in subview's parent matrix.
  183. arma_inline eT operator*() const { return iterator_base::M->m.values[actual_pos]; }
  184. arma_inline uword row() const { return internal_row; }
  185. inline arma_hot bool operator!=(const const_iterator& rhs) const;
  186. inline arma_hot bool operator==(const const_iterator& rhs) const;
  187. inline arma_hot bool operator!=(const typename SpMat<eT>::const_iterator& rhs) const;
  188. inline arma_hot bool operator==(const typename SpMat<eT>::const_iterator& rhs) const;
  189. inline arma_hot bool operator!=(const const_row_iterator& rhs) const;
  190. inline arma_hot bool operator==(const const_row_iterator& rhs) const;
  191. inline arma_hot bool operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const;
  192. inline arma_hot bool operator==(const typename SpMat<eT>::const_row_iterator& rhs) const;
  193. };
  194. class row_iterator : public const_row_iterator
  195. {
  196. public:
  197. inline row_iterator(SpSubview& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { }
  198. inline row_iterator(SpSubview& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { }
  199. inline row_iterator(const row_iterator& other) : const_row_iterator(other) { }
  200. inline arma_hot SpValProxy<SpSubview<eT> > operator*();
  201. // overloads needed for return type correctness
  202. inline arma_hot row_iterator& operator++();
  203. inline arma_warn_unused row_iterator operator++(int);
  204. inline arma_hot row_iterator& operator--();
  205. inline arma_warn_unused row_iterator operator--(int);
  206. // This has a different value_type than iterator_base.
  207. typedef SpValProxy<SpSubview<eT> > value_type;
  208. typedef const SpValProxy<SpSubview<eT> >* pointer;
  209. typedef const SpValProxy<SpSubview<eT> >& reference;
  210. };
  211. inline iterator begin();
  212. inline const_iterator begin() const;
  213. inline const_iterator cbegin() const;
  214. inline iterator begin_col(const uword col_num);
  215. inline const_iterator begin_col(const uword col_num) const;
  216. inline row_iterator begin_row(const uword row_num = 0);
  217. inline const_row_iterator begin_row(const uword row_num = 0) const;
  218. inline iterator end();
  219. inline const_iterator end() const;
  220. inline const_iterator cend() const;
  221. inline row_iterator end_row();
  222. inline const_row_iterator end_row() const;
  223. inline row_iterator end_row(const uword row_num);
  224. inline const_row_iterator end_row(const uword row_num) const;
  225. //! don't use this unless you're writing internal Armadillo code
  226. arma_inline bool is_alias(const SpMat<eT>& X) const;
  227. private:
  228. friend class SpMat<eT>;
  229. friend class SpSubview_col<eT>;
  230. friend class SpSubview_row<eT>;
  231. SpSubview();
  232. inline arma_warn_unused eT& insert_element(const uword in_row, const uword in_col, const eT in_val = eT(0));
  233. inline void delete_element(const uword in_row, const uword in_col);
  234. inline void invalidate_cache() const;
  235. };
  236. template<typename eT>
  237. class SpSubview_col : public SpSubview<eT>
  238. {
  239. public:
  240. typedef eT elem_type;
  241. typedef typename get_pod_type<elem_type>::result pod_type;
  242. static const bool is_row = false;
  243. static const bool is_col = true;
  244. static const bool is_xvec = false;
  245. inline void operator= (const SpSubview<eT>& x);
  246. inline void operator= (const SpSubview_col& x);
  247. template<typename T1> inline void operator= (const SpBase<eT,T1>& x);
  248. template<typename T1> inline void operator= (const Base<eT,T1>& x);
  249. inline const SpOp<SpSubview_col<eT>,spop_htrans> t() const;
  250. inline const SpOp<SpSubview_col<eT>,spop_htrans> ht() const;
  251. inline const SpOp<SpSubview_col<eT>,spop_strans> st() const;
  252. protected:
  253. inline SpSubview_col(const SpMat<eT>& in_m, const uword in_col);
  254. inline SpSubview_col( SpMat<eT>& in_m, const uword in_col);
  255. inline SpSubview_col(const SpMat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows);
  256. inline SpSubview_col( SpMat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows);
  257. private:
  258. friend class SpMat<eT>;
  259. friend class SpSubview<eT>;
  260. SpSubview_col();
  261. };
  262. template<typename eT>
  263. class SpSubview_row : public SpSubview<eT>
  264. {
  265. public:
  266. typedef eT elem_type;
  267. typedef typename get_pod_type<elem_type>::result pod_type;
  268. static const bool is_row = true;
  269. static const bool is_col = false;
  270. static const bool is_xvec = false;
  271. inline void operator= (const SpSubview<eT>& x);
  272. inline void operator= (const SpSubview_row& x);
  273. template<typename T1> inline void operator= (const SpBase<eT,T1>& x);
  274. template<typename T1> inline void operator= (const Base<eT,T1>& x);
  275. inline const SpOp<SpSubview_row<eT>,spop_htrans> t() const;
  276. inline const SpOp<SpSubview_row<eT>,spop_htrans> ht() const;
  277. inline const SpOp<SpSubview_row<eT>,spop_strans> st() const;
  278. protected:
  279. inline SpSubview_row(const SpMat<eT>& in_m, const uword in_row);
  280. inline SpSubview_row( SpMat<eT>& in_m, const uword in_row);
  281. inline SpSubview_row(const SpMat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols);
  282. inline SpSubview_row( SpMat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols);
  283. private:
  284. friend class SpMat<eT>;
  285. friend class SpSubview<eT>;
  286. SpSubview_row();
  287. };
  288. //! @}