1 // SPDX-License-Identifier: Apache-2.0 2 // 3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au) 4 // Copyright 2008-2016 National ICT Australia (NICTA) 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // ------------------------------------------------------------------------ 17 18 19 //! \addtogroup SpSubview 20 //! @{ 21 22 23 template<typename eT> 24 class SpSubview : public SpBase< eT, SpSubview<eT> > 25 { 26 public: 27 28 const SpMat<eT>& m; 29 30 typedef eT elem_type; 31 typedef typename get_pod_type<elem_type>::result pod_type; 32 33 static constexpr bool is_row = false; 34 static constexpr bool is_col = false; 35 static constexpr bool is_xvec = false; 36 37 const uword aux_row1; 38 const uword aux_col1; 39 const uword n_rows; 40 const uword n_cols; 41 const uword n_elem; 42 const uword n_nonzero; 43 44 protected: 45 46 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); 47 48 public: 49 50 inline ~SpSubview(); 51 inline SpSubview() = delete; 52 53 inline SpSubview(const SpSubview& in); 54 inline SpSubview( SpSubview&& in); 55 56 inline const SpSubview& operator+= (const eT val); 57 inline const SpSubview& operator-= (const eT val); 58 inline const SpSubview& operator*= (const eT val); 59 inline const SpSubview& operator/= (const eT val); 60 61 inline const SpSubview& operator=(const SpSubview& x); 62 63 template<typename T1> inline const SpSubview& operator= (const Base<eT, T1>& x); 64 template<typename T1> inline const SpSubview& operator+=(const Base<eT, T1>& x); 65 template<typename T1> inline const SpSubview& operator-=(const Base<eT, T1>& x); 66 template<typename T1> inline const SpSubview& operator*=(const Base<eT, T1>& x); 67 template<typename T1> inline const SpSubview& operator%=(const Base<eT, T1>& x); 68 template<typename T1> inline const SpSubview& operator/=(const Base<eT, T1>& x); 69 70 template<typename T1> inline const SpSubview& operator_equ_common(const SpBase<eT, T1>& x); 71 72 template<typename T1> inline const SpSubview& operator= (const SpBase<eT, T1>& x); 73 template<typename T1> inline const SpSubview& operator+=(const SpBase<eT, T1>& x); 74 template<typename T1> inline const SpSubview& operator-=(const SpBase<eT, T1>& x); 75 template<typename T1> inline const SpSubview& operator*=(const SpBase<eT, T1>& x); 76 template<typename T1> inline const SpSubview& operator%=(const SpBase<eT, T1>& x); 77 template<typename T1> inline const SpSubview& operator/=(const SpBase<eT, T1>& x); 78 79 /* 80 inline static void extract(SpMat<eT>& out, const SpSubview& in); 81 82 inline static void plus_inplace(Mat<eT>& out, const subview& in); 83 inline static void minus_inplace(Mat<eT>& out, const subview& in); 84 inline static void schur_inplace(Mat<eT>& out, const subview& in); 85 inline static void div_inplace(Mat<eT>& out, const subview& in); 86 */ 87 88 template<typename functor> inline void for_each(functor F); 89 template<typename functor> inline void for_each(functor F) const; 90 91 template<typename functor> inline void transform(functor F); 92 93 inline void replace(const eT old_val, const eT new_val); 94 95 inline void clean(const pod_type threshold); 96 97 inline void clamp(const eT min_val, const eT max_val); 98 99 inline void fill(const eT val); 100 inline void zeros(); 101 inline void ones(); 102 inline void eye(); 103 inline void randu(); 104 inline void randn(); 105 106 107 arma_hot inline SpSubview_MapMat_val<eT> operator[](const uword i); 108 arma_hot inline eT operator[](const uword i) const; 109 110 arma_hot inline SpSubview_MapMat_val<eT> operator()(const uword i); 111 arma_hot inline eT operator()(const uword i) const; 112 113 arma_hot inline SpSubview_MapMat_val<eT> operator()(const uword in_row, const uword in_col); 114 arma_hot inline eT operator()(const uword in_row, const uword in_col) const; 115 116 arma_hot inline SpSubview_MapMat_val<eT> at(const uword i); 117 arma_hot inline eT at(const uword i) const; 118 119 arma_hot inline SpSubview_MapMat_val<eT> at(const uword in_row, const uword in_col); 120 arma_hot inline eT at(const uword in_row, const uword in_col) const; 121 122 inline bool check_overlap(const SpSubview& x) const; 123 124 inline bool is_vec() const; 125 126 inline SpSubview_row<eT> row(const uword row_num); 127 inline const SpSubview_row<eT> row(const uword row_num) const; 128 129 inline SpSubview_col<eT> col(const uword col_num); 130 inline const SpSubview_col<eT> col(const uword col_num) const; 131 132 inline SpSubview rows(const uword in_row1, const uword in_row2); 133 inline const SpSubview rows(const uword in_row1, const uword in_row2) const; 134 135 inline SpSubview cols(const uword in_col1, const uword in_col2); 136 inline const SpSubview cols(const uword in_col1, const uword in_col2) const; 137 138 inline SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2); 139 inline const SpSubview submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const; 140 141 inline SpSubview submat(const span& row_span, const span& col_span); 142 inline const SpSubview submat(const span& row_span, const span& col_span) const; 143 144 inline SpSubview operator()(const uword row_num, const span& col_span); 145 inline const SpSubview operator()(const uword row_num, const span& col_span) const; 146 147 inline SpSubview operator()(const span& row_span, const uword col_num); 148 inline const SpSubview operator()(const span& row_span, const uword col_num) const; 149 150 inline SpSubview operator()(const span& row_span, const span& col_span); 151 inline const SpSubview operator()(const span& row_span, const span& col_span) const; 152 153 154 inline void swap_rows(const uword in_row1, const uword in_row2); 155 inline void swap_cols(const uword in_col1, const uword in_col2); 156 157 // Forward declarations. 158 class iterator_base; 159 class const_iterator; 160 class iterator; 161 class const_row_iterator; 162 class row_iterator; 163 164 // Similar to SpMat iterators but automatically iterates past and ignores values not in the subview. 165 class iterator_base 166 { 167 public: 168 169 inline iterator_base(const SpSubview& in_M); 170 inline iterator_base(const SpSubview& in_M, const uword col, const uword pos); 171 col() const172 arma_inline uword col() const { return internal_col; } pos() const173 arma_inline uword pos() const { return internal_pos; } 174 175 arma_aligned const SpSubview* M; 176 arma_aligned uword internal_col; 177 arma_aligned uword internal_pos; 178 179 typedef std::bidirectional_iterator_tag iterator_category; 180 typedef eT value_type; 181 typedef std::ptrdiff_t difference_type; // TODO: not certain on this one 182 typedef const eT* pointer; 183 typedef const eT& reference; 184 }; 185 186 class const_iterator : public iterator_base 187 { 188 public: 189 190 inline const_iterator(const SpSubview& in_M, uword initial_pos = 0); 191 inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col); 192 inline const_iterator(const SpSubview& in_M, uword in_row, uword in_col, uword in_pos, uword skip_pos); 193 inline const_iterator(const const_iterator& other); 194 195 arma_inline eT operator*() const; 196 197 // Don't hold location internally; call "dummy" methods to get that information. row() const198 arma_inline uword row() const { return iterator_base::M->m.row_indices[iterator_base::internal_pos + skip_pos] - iterator_base::M->aux_row1; } 199 200 inline arma_hot const_iterator& operator++(); 201 inline arma_warn_unused const_iterator operator++(int); 202 203 inline arma_hot const_iterator& operator--(); 204 inline arma_warn_unused const_iterator operator--(int); 205 206 inline arma_hot bool operator!=(const const_iterator& rhs) const; 207 inline arma_hot bool operator==(const const_iterator& rhs) const; 208 209 inline arma_hot bool operator!=(const typename SpMat<eT>::const_iterator& rhs) const; 210 inline arma_hot bool operator==(const typename SpMat<eT>::const_iterator& rhs) const; 211 212 inline arma_hot bool operator!=(const const_row_iterator& rhs) const; 213 inline arma_hot bool operator==(const const_row_iterator& rhs) const; 214 215 inline arma_hot bool operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const; 216 inline arma_hot bool operator==(const typename SpMat<eT>::const_row_iterator& rhs) const; 217 218 arma_aligned uword skip_pos; // not used in row_iterator or const_row_iterator 219 }; 220 221 class iterator : public const_iterator 222 { 223 public: 224 iterator(SpSubview & in_M,const uword initial_pos=0)225 inline iterator(SpSubview& in_M, const uword initial_pos = 0) : const_iterator(in_M, initial_pos) { } iterator(SpSubview & in_M,const uword in_row,const uword in_col)226 inline iterator(SpSubview& in_M, const uword in_row, const uword in_col) : const_iterator(in_M, in_row, in_col) { } iterator(SpSubview & in_M,const uword in_row,const uword in_col,const uword in_pos,const uword in_skip_pos)227 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) { } iterator(const iterator & other)228 inline iterator(const iterator& other) : const_iterator(other) { } 229 230 inline arma_hot SpValProxy< SpSubview<eT> > operator*(); 231 232 // overloads needed for return type correctness 233 inline arma_hot iterator& operator++(); 234 inline arma_warn_unused iterator operator++(int); 235 236 inline arma_hot iterator& operator--(); 237 inline arma_warn_unused iterator operator--(int); 238 239 // This has a different value_type than iterator_base. 240 typedef SpValProxy< SpSubview<eT> > value_type; 241 typedef const SpValProxy< SpSubview<eT> >* pointer; 242 typedef const SpValProxy< SpSubview<eT> >& reference; 243 }; 244 245 class const_row_iterator : public iterator_base 246 { 247 public: 248 249 inline const_row_iterator(); 250 inline const_row_iterator(const SpSubview& in_M, uword initial_pos = 0); 251 inline const_row_iterator(const SpSubview& in_M, uword in_row, uword in_col); 252 inline const_row_iterator(const const_row_iterator& other); 253 254 inline arma_hot const_row_iterator& operator++(); 255 inline arma_warn_unused const_row_iterator operator++(int); 256 257 inline arma_hot const_row_iterator& operator--(); 258 inline arma_warn_unused const_row_iterator operator--(int); 259 260 uword internal_row; // Hold row internally because we use internal_pos differently. 261 uword actual_pos; // Actual position in subview's parent matrix. 262 operator *() const263 arma_inline eT operator*() const { return iterator_base::M->m.values[actual_pos]; } 264 row() const265 arma_inline uword row() const { return internal_row; } 266 267 inline arma_hot bool operator!=(const const_iterator& rhs) const; 268 inline arma_hot bool operator==(const const_iterator& rhs) const; 269 270 inline arma_hot bool operator!=(const typename SpMat<eT>::const_iterator& rhs) const; 271 inline arma_hot bool operator==(const typename SpMat<eT>::const_iterator& rhs) const; 272 273 inline arma_hot bool operator!=(const const_row_iterator& rhs) const; 274 inline arma_hot bool operator==(const const_row_iterator& rhs) const; 275 276 inline arma_hot bool operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const; 277 inline arma_hot bool operator==(const typename SpMat<eT>::const_row_iterator& rhs) const; 278 }; 279 280 class row_iterator : public const_row_iterator 281 { 282 public: 283 row_iterator(SpSubview & in_M,uword initial_pos=0)284 inline row_iterator(SpSubview& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { } row_iterator(SpSubview & in_M,uword in_row,uword in_col)285 inline row_iterator(SpSubview& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { } row_iterator(const row_iterator & other)286 inline row_iterator(const row_iterator& other) : const_row_iterator(other) { } 287 288 inline arma_hot SpValProxy< SpSubview<eT> > operator*(); 289 290 // overloads needed for return type correctness 291 inline arma_hot row_iterator& operator++(); 292 inline arma_warn_unused row_iterator operator++(int); 293 294 inline arma_hot row_iterator& operator--(); 295 inline arma_warn_unused row_iterator operator--(int); 296 297 // This has a different value_type than iterator_base. 298 typedef SpValProxy< SpSubview<eT> > value_type; 299 typedef const SpValProxy< SpSubview<eT> >* pointer; 300 typedef const SpValProxy< SpSubview<eT> >& reference; 301 }; 302 303 inline iterator begin(); 304 inline const_iterator begin() const; 305 inline const_iterator cbegin() const; 306 307 inline iterator begin_col(const uword col_num); 308 inline const_iterator begin_col(const uword col_num) const; 309 310 inline row_iterator begin_row(const uword row_num = 0); 311 inline const_row_iterator begin_row(const uword row_num = 0) const; 312 313 inline iterator end(); 314 inline const_iterator end() const; 315 inline const_iterator cend() const; 316 317 inline row_iterator end_row(); 318 inline const_row_iterator end_row() const; 319 320 inline row_iterator end_row(const uword row_num); 321 inline const_row_iterator end_row(const uword row_num) const; 322 323 //! don't use this unless you're writing internal Armadillo code 324 arma_inline bool is_alias(const SpMat<eT>& X) const; 325 326 327 private: 328 329 friend class SpMat<eT>; 330 friend class SpSubview_col<eT>; 331 friend class SpSubview_row<eT>; 332 friend class SpValProxy< SpSubview<eT> >; // allow SpValProxy to call insert_element() and delete_element() 333 334 inline arma_warn_unused eT& insert_element(const uword in_row, const uword in_col, const eT in_val = eT(0)); 335 inline void delete_element(const uword in_row, const uword in_col); 336 337 inline void invalidate_cache() const; 338 }; 339 340 341 342 template<typename eT> 343 class SpSubview_col : public SpSubview<eT> 344 { 345 public: 346 347 typedef eT elem_type; 348 typedef typename get_pod_type<elem_type>::result pod_type; 349 350 static constexpr bool is_row = false; 351 static constexpr bool is_col = true; 352 static constexpr bool is_xvec = false; 353 354 inline void operator= (const SpSubview<eT>& x); 355 inline void operator= (const SpSubview_col& x); 356 357 template<typename T1> inline void operator= (const SpBase<eT,T1>& x); 358 template<typename T1> inline void operator= (const Base<eT,T1>& x); 359 360 inline arma_warn_unused const SpOp<SpSubview_col<eT>,spop_htrans> t() const; 361 inline arma_warn_unused const SpOp<SpSubview_col<eT>,spop_htrans> ht() const; 362 inline arma_warn_unused const SpOp<SpSubview_col<eT>,spop_strans> st() const; 363 364 365 protected: 366 367 inline SpSubview_col(const SpMat<eT>& in_m, const uword in_col); 368 inline SpSubview_col(const SpMat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows); 369 inline SpSubview_col() = delete; 370 371 372 private: 373 374 friend class SpMat<eT>; 375 friend class SpSubview<eT>; 376 }; 377 378 379 380 template<typename eT> 381 class SpSubview_row : public SpSubview<eT> 382 { 383 public: 384 385 typedef eT elem_type; 386 typedef typename get_pod_type<elem_type>::result pod_type; 387 388 static constexpr bool is_row = true; 389 static constexpr bool is_col = false; 390 static constexpr bool is_xvec = false; 391 392 inline void operator= (const SpSubview<eT>& x); 393 inline void operator= (const SpSubview_row& x); 394 395 template<typename T1> inline void operator= (const SpBase<eT,T1>& x); 396 template<typename T1> inline void operator= (const Base<eT,T1>& x); 397 398 inline arma_warn_unused const SpOp<SpSubview_row<eT>,spop_htrans> t() const; 399 inline arma_warn_unused const SpOp<SpSubview_row<eT>,spop_htrans> ht() const; 400 inline arma_warn_unused const SpOp<SpSubview_row<eT>,spop_strans> st() const; 401 402 403 protected: 404 405 inline SpSubview_row(const SpMat<eT>& in_m, const uword in_row); 406 inline SpSubview_row(const SpMat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols); 407 inline SpSubview_row() = delete; 408 409 410 private: 411 412 friend class SpMat<eT>; 413 friend class SpSubview<eT>; 414 }; 415 416 417 418 //! @} 419