1 | // Copyright (C) 2011-2014 Ryan Curtin |
---|
2 | // Copyright (C) 2012-2015 Conrad Sanderson |
---|
3 | // Copyright (C) 2011 Matthew Amidon |
---|
4 | // |
---|
5 | // This Source Code Form is subject to the terms of the Mozilla Public |
---|
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this |
---|
7 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. |
---|
8 | |
---|
9 | //! \addtogroup SpMat |
---|
10 | //! @{ |
---|
11 | |
---|
12 | //! Sparse matrix class, with data stored in compressed sparse column (CSC) format |
---|
13 | |
---|
14 | template<typename eT> |
---|
15 | class SpMat : public SpBase< eT, SpMat<eT> > |
---|
16 | { |
---|
17 | public: |
---|
18 | |
---|
19 | typedef eT elem_type; //!< the type of elements stored in the matrix |
---|
20 | typedef typename get_pod_type<eT>::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 |
---|
21 | |
---|
22 | static const bool is_row = false; |
---|
23 | static const bool is_col = false; |
---|
24 | |
---|
25 | const uword n_rows; //!< number of rows in the matrix (read-only) |
---|
26 | const uword n_cols; //!< number of columns in the matrix (read-only) |
---|
27 | const uword n_elem; //!< number of elements in the matrix (read-only) |
---|
28 | const uword n_nonzero; //!< number of nonzero elements in the matrix (read-only) |
---|
29 | const uword vec_state; //!< 0: matrix; 1: column vector; 2: row vector |
---|
30 | |
---|
31 | // So that SpValProxy can call add_element() and delete_element(). |
---|
32 | friend class SpValProxy<SpMat<eT> >; |
---|
33 | friend class SpSubview<eT>; |
---|
34 | |
---|
35 | /** |
---|
36 | * The memory used to store the values of the matrix. |
---|
37 | * In accordance with the CSC format, this stores only the actual values. |
---|
38 | * The correct locations of the values are assembled from the row indices |
---|
39 | * and the column pointers. |
---|
40 | * |
---|
41 | * The length of this array is (n_nonzero + 1); the final value ensures |
---|
42 | * the integrity of iterators. If you are planning on resizing this vector, |
---|
43 | * it's probably best to use mem_resize() instead, which automatically sets |
---|
44 | * the length to (n_nonzero + 1). If you need to allocate the memory yourself |
---|
45 | * for some reason, be sure to set values[n_nonzero] to 0. |
---|
46 | */ |
---|
47 | arma_aligned const eT* const values; |
---|
48 | |
---|
49 | /** |
---|
50 | * The row indices of each value. row_indices[i] is the row of values[i]. |
---|
51 | * |
---|
52 | * The length of this array is (n_nonzero + 1); the final value ensures |
---|
53 | * the integrity of iterators. If you are planning on resizing this vector, |
---|
54 | * it's probably best to use mem_resize() instead. If you need to allocate |
---|
55 | * the memory yourself for some reason, be sure to set row_indices[n_nonzero] to 0. |
---|
56 | */ |
---|
57 | arma_aligned const uword* const row_indices; |
---|
58 | |
---|
59 | /** |
---|
60 | * The column pointers. This stores the index of the first item in column i. |
---|
61 | * That is, values[col_ptrs[i]] is the first value in column i, and it is in |
---|
62 | * the row indicated by row_indices[col_ptrs[i]]. |
---|
63 | * |
---|
64 | * This array is of length (n_cols + 2); the element col_ptrs[n_cols] should |
---|
65 | * be equal to n_nonzero, and the element col_ptrs[n_cols + 1] is an invalid |
---|
66 | * very large value that ensures the integrity of iterators. |
---|
67 | * |
---|
68 | * The col_ptrs array is set by the init() function (which is called by the |
---|
69 | * constructors and set_size() and other functions that set the size of the |
---|
70 | * matrix), so allocating col_ptrs by hand should not be necessary. |
---|
71 | */ |
---|
72 | arma_aligned const uword* const col_ptrs; |
---|
73 | |
---|
74 | inline SpMat(); //! Size will be 0x0 (empty). |
---|
75 | inline ~SpMat(); |
---|
76 | |
---|
77 | inline SpMat(const uword in_rows, const uword in_cols); |
---|
78 | |
---|
79 | inline SpMat(const char* text); |
---|
80 | inline const SpMat& operator=(const char* text); |
---|
81 | inline SpMat(const std::string& text); |
---|
82 | inline const SpMat& operator=(const std::string& text); |
---|
83 | inline SpMat(const SpMat<eT>& x); |
---|
84 | |
---|
85 | |
---|
86 | #if defined(ARMA_USE_CXX11) |
---|
87 | inline SpMat(SpMat&& m); |
---|
88 | inline const SpMat& operator=(SpMat&& m); |
---|
89 | #endif |
---|
90 | |
---|
91 | template<typename T1, typename T2, typename T3> |
---|
92 | 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); |
---|
93 | |
---|
94 | template<typename T1, typename T2> |
---|
95 | inline SpMat(const Base<uword,T1>& locations, const Base<eT,T2>& values, const bool sort_locations = true); |
---|
96 | |
---|
97 | template<typename T1, typename T2> |
---|
98 | 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); |
---|
99 | |
---|
100 | template<typename T1, typename T2> |
---|
101 | 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); |
---|
102 | |
---|
103 | inline const SpMat& operator=(const eT val); //! Sets size to 1x1. |
---|
104 | inline const SpMat& operator*=(const eT val); |
---|
105 | inline const SpMat& operator/=(const eT val); |
---|
106 | // operator+=(val) and operator-=(val) are not defined as they don't make sense for sparse matrices |
---|
107 | |
---|
108 | /** |
---|
109 | * Operators on other sparse matrices. These work as though you would expect. |
---|
110 | */ |
---|
111 | inline const SpMat& operator=(const SpMat& m); |
---|
112 | inline const SpMat& operator+=(const SpMat& m); |
---|
113 | inline const SpMat& operator-=(const SpMat& m); |
---|
114 | inline const SpMat& operator*=(const SpMat& m); |
---|
115 | inline const SpMat& operator%=(const SpMat& m); |
---|
116 | inline const SpMat& operator/=(const SpMat& m); |
---|
117 | |
---|
118 | /** |
---|
119 | * Operators on other regular matrices. These work as though you would expect. |
---|
120 | */ |
---|
121 | template<typename T1> inline explicit SpMat(const Base<eT, T1>& m); |
---|
122 | template<typename T1> inline const SpMat& operator=(const Base<eT, T1>& m); |
---|
123 | template<typename T1> inline const SpMat& operator+=(const Base<eT, T1>& m); |
---|
124 | template<typename T1> inline const SpMat& operator-=(const Base<eT, T1>& m); |
---|
125 | template<typename T1> inline const SpMat& operator*=(const Base<eT, T1>& m); |
---|
126 | template<typename T1> inline const SpMat& operator/=(const Base<eT, T1>& m); |
---|
127 | template<typename T1> inline const SpMat& operator%=(const Base<eT, T1>& m); |
---|
128 | |
---|
129 | |
---|
130 | //! construction of complex matrix out of two non-complex matrices; |
---|
131 | template<typename T1, typename T2> |
---|
132 | inline explicit SpMat(const SpBase<pod_type, T1>& A, const SpBase<pod_type, T2>& B); |
---|
133 | |
---|
134 | /** |
---|
135 | * Operations on sparse subviews. |
---|
136 | */ |
---|
137 | inline SpMat(const SpSubview<eT>& X); |
---|
138 | inline const SpMat& operator=(const SpSubview<eT>& X); |
---|
139 | inline const SpMat& operator+=(const SpSubview<eT>& X); |
---|
140 | inline const SpMat& operator-=(const SpSubview<eT>& X); |
---|
141 | inline const SpMat& operator*=(const SpSubview<eT>& X); |
---|
142 | inline const SpMat& operator%=(const SpSubview<eT>& X); |
---|
143 | inline const SpMat& operator/=(const SpSubview<eT>& X); |
---|
144 | |
---|
145 | // delayed unary ops |
---|
146 | template<typename T1, typename spop_type> inline SpMat(const SpOp<T1, spop_type>& X); |
---|
147 | template<typename T1, typename spop_type> inline const SpMat& operator=(const SpOp<T1, spop_type>& X); |
---|
148 | template<typename T1, typename spop_type> inline const SpMat& operator+=(const SpOp<T1, spop_type>& X); |
---|
149 | template<typename T1, typename spop_type> inline const SpMat& operator-=(const SpOp<T1, spop_type>& X); |
---|
150 | template<typename T1, typename spop_type> inline const SpMat& operator*=(const SpOp<T1, spop_type>& X); |
---|
151 | template<typename T1, typename spop_type> inline const SpMat& operator%=(const SpOp<T1, spop_type>& X); |
---|
152 | template<typename T1, typename spop_type> inline const SpMat& operator/=(const SpOp<T1, spop_type>& X); |
---|
153 | |
---|
154 | // delayed binary ops |
---|
155 | template<typename T1, typename T2, typename spglue_type> inline SpMat(const SpGlue<T1, T2, spglue_type>& X); |
---|
156 | template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator=(const SpGlue<T1, T2, spglue_type>& X); |
---|
157 | template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator+=(const SpGlue<T1, T2, spglue_type>& X); |
---|
158 | template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator-=(const SpGlue<T1, T2, spglue_type>& X); |
---|
159 | template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator*=(const SpGlue<T1, T2, spglue_type>& X); |
---|
160 | template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator%=(const SpGlue<T1, T2, spglue_type>& X); |
---|
161 | template<typename T1, typename T2, typename spglue_type> inline const SpMat& operator/=(const SpGlue<T1, T2, spglue_type>& X); |
---|
162 | |
---|
163 | // delayed mixted-type unary ops |
---|
164 | template<typename T1, typename spop_type> inline SpMat(const mtSpOp<eT, T1, spop_type>& X); |
---|
165 | template<typename T1, typename spop_type> inline const SpMat& operator=(const mtSpOp<eT, T1, spop_type>& X); |
---|
166 | template<typename T1, typename spop_type> inline const SpMat& operator+=(const mtSpOp<eT, T1, spop_type>& X); |
---|
167 | template<typename T1, typename spop_type> inline const SpMat& operator-=(const mtSpOp<eT, T1, spop_type>& X); |
---|
168 | template<typename T1, typename spop_type> inline const SpMat& operator*=(const mtSpOp<eT, T1, spop_type>& X); |
---|
169 | template<typename T1, typename spop_type> inline const SpMat& operator%=(const mtSpOp<eT, T1, spop_type>& X); |
---|
170 | template<typename T1, typename spop_type> inline const SpMat& operator/=(const mtSpOp<eT, T1, spop_type>& X); |
---|
171 | |
---|
172 | /** |
---|
173 | * Submatrix methods. |
---|
174 | */ |
---|
175 | arma_inline SpSubview<eT> row(const uword row_num); |
---|
176 | arma_inline const SpSubview<eT> row(const uword row_num) const; |
---|
177 | |
---|
178 | inline SpSubview<eT> operator()(const uword row_num, const span& col_span); |
---|
179 | inline const SpSubview<eT> operator()(const uword row_num, const span& col_span) const; |
---|
180 | |
---|
181 | arma_inline SpSubview<eT> col(const uword col_num); |
---|
182 | arma_inline const SpSubview<eT> col(const uword col_num) const; |
---|
183 | |
---|
184 | inline SpSubview<eT> operator()(const span& row_span, const uword col_num); |
---|
185 | inline const SpSubview<eT> operator()(const span& row_span, const uword col_num) const; |
---|
186 | |
---|
187 | arma_inline SpSubview<eT> rows(const uword in_row1, const uword in_row2); |
---|
188 | arma_inline const SpSubview<eT> rows(const uword in_row1, const uword in_row2) const; |
---|
189 | |
---|
190 | arma_inline SpSubview<eT> cols(const uword in_col1, const uword in_col2); |
---|
191 | arma_inline const SpSubview<eT> cols(const uword in_col1, const uword in_col2) const; |
---|
192 | |
---|
193 | arma_inline SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2); |
---|
194 | arma_inline const SpSubview<eT> submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const; |
---|
195 | |
---|
196 | arma_inline SpSubview<eT> submat(const uword in_row1, const uword in_col1, const SizeMat& s); |
---|
197 | arma_inline const SpSubview<eT> submat(const uword in_row1, const uword in_col1, const SizeMat& s) const; |
---|
198 | |
---|
199 | inline SpSubview<eT> submat (const span& row_span, const span& col_span); |
---|
200 | inline const SpSubview<eT> submat (const span& row_span, const span& col_span) const; |
---|
201 | |
---|
202 | inline SpSubview<eT> operator()(const span& row_span, const span& col_span); |
---|
203 | inline const SpSubview<eT> operator()(const span& row_span, const span& col_span) const; |
---|
204 | |
---|
205 | arma_inline SpSubview<eT> operator()(const uword in_row1, const uword in_col1, const SizeMat& s); |
---|
206 | arma_inline const SpSubview<eT> operator()(const uword in_row1, const uword in_col1, const SizeMat& s) const; |
---|
207 | |
---|
208 | |
---|
209 | inline SpSubview<eT> head_rows(const uword N); |
---|
210 | inline const SpSubview<eT> head_rows(const uword N) const; |
---|
211 | |
---|
212 | inline SpSubview<eT> tail_rows(const uword N); |
---|
213 | inline const SpSubview<eT> tail_rows(const uword N) const; |
---|
214 | |
---|
215 | inline SpSubview<eT> head_cols(const uword N); |
---|
216 | inline const SpSubview<eT> head_cols(const uword N) const; |
---|
217 | |
---|
218 | inline SpSubview<eT> tail_cols(const uword N); |
---|
219 | inline const SpSubview<eT> tail_cols(const uword N) const; |
---|
220 | |
---|
221 | |
---|
222 | inline spdiagview<eT> diag(const sword in_id = 0); |
---|
223 | inline const spdiagview<eT> diag(const sword in_id = 0) const; |
---|
224 | |
---|
225 | |
---|
226 | inline void swap_rows(const uword in_row1, const uword in_row2); |
---|
227 | inline void swap_cols(const uword in_col1, const uword in_col2); |
---|
228 | |
---|
229 | inline void shed_row(const uword row_num); |
---|
230 | inline void shed_col(const uword col_num); |
---|
231 | |
---|
232 | inline void shed_rows(const uword in_row1, const uword in_row2); |
---|
233 | inline void shed_cols(const uword in_col1, const uword in_col2); |
---|
234 | |
---|
235 | |
---|
236 | /** |
---|
237 | * Element access; access the i'th element (works identically to the Mat accessors). |
---|
238 | * If there is nothing at element i, 0 is returned. |
---|
239 | * |
---|
240 | * @param i Element to access. |
---|
241 | */ |
---|
242 | arma_inline arma_warn_unused SpValProxy<SpMat<eT> > operator[] (const uword i); |
---|
243 | arma_inline arma_warn_unused eT operator[] (const uword i) const; |
---|
244 | arma_inline arma_warn_unused SpValProxy<SpMat<eT> > at (const uword i); |
---|
245 | arma_inline arma_warn_unused eT at (const uword i) const; |
---|
246 | arma_inline arma_warn_unused SpValProxy<SpMat<eT> > operator() (const uword i); |
---|
247 | arma_inline arma_warn_unused eT operator() (const uword i) const; |
---|
248 | |
---|
249 | /** |
---|
250 | * Element access; access the element at row in_row and column in_col. |
---|
251 | * If there is nothing at that position, 0 is returned. |
---|
252 | */ |
---|
253 | arma_inline arma_warn_unused SpValProxy<SpMat<eT> > at (const uword in_row, const uword in_col); |
---|
254 | arma_inline arma_warn_unused eT at (const uword in_row, const uword in_col) const; |
---|
255 | arma_inline arma_warn_unused SpValProxy<SpMat<eT> > operator() (const uword in_row, const uword in_col); |
---|
256 | arma_inline arma_warn_unused eT operator() (const uword in_row, const uword in_col) const; |
---|
257 | |
---|
258 | |
---|
259 | /** |
---|
260 | * Information boolean checks on matrices. |
---|
261 | */ |
---|
262 | arma_inline arma_warn_unused bool is_empty() const; |
---|
263 | arma_inline arma_warn_unused bool is_vec() const; |
---|
264 | arma_inline arma_warn_unused bool is_rowvec() const; |
---|
265 | arma_inline arma_warn_unused bool is_colvec() const; |
---|
266 | arma_inline arma_warn_unused bool is_square() const; |
---|
267 | inline arma_warn_unused bool is_finite() const; |
---|
268 | |
---|
269 | arma_inline arma_warn_unused bool in_range(const uword i) const; |
---|
270 | arma_inline arma_warn_unused bool in_range(const span& x) const; |
---|
271 | |
---|
272 | arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col) const; |
---|
273 | arma_inline arma_warn_unused bool in_range(const span& row_span, const uword in_col) const; |
---|
274 | arma_inline arma_warn_unused bool in_range(const uword in_row, const span& col_span) const; |
---|
275 | arma_inline arma_warn_unused bool in_range(const span& row_span, const span& col_span) const; |
---|
276 | |
---|
277 | arma_inline arma_warn_unused bool in_range(const uword in_row, const uword in_col, const SizeMat& s) const; |
---|
278 | |
---|
279 | /** |
---|
280 | * Printing the matrix. |
---|
281 | * |
---|
282 | * @param extra_text Text to prepend to output. |
---|
283 | */ |
---|
284 | inline void impl_print(const std::string& extra_text) const; |
---|
285 | inline void impl_print(std::ostream& user_stream, const std::string& extra_text) const; |
---|
286 | |
---|
287 | inline void impl_raw_print(const std::string& extra_text) const; |
---|
288 | inline void impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const; |
---|
289 | |
---|
290 | inline void impl_print_dense(const std::string& extra_text) const; |
---|
291 | inline void impl_print_dense(std::ostream& user_stream, const std::string& extra_text) const; |
---|
292 | |
---|
293 | inline void impl_raw_print_dense(const std::string& extra_text) const; |
---|
294 | inline void impl_raw_print_dense(std::ostream& user_stream, const std::string& extra_text) const; |
---|
295 | |
---|
296 | //! Copy the size of another matrix. |
---|
297 | template<typename eT2> inline void copy_size(const SpMat<eT2>& m); |
---|
298 | template<typename eT2> inline void copy_size(const Mat<eT2>& m); |
---|
299 | |
---|
300 | /** |
---|
301 | * Set the size of the matrix; the matrix will be sized as a column vector |
---|
302 | * |
---|
303 | * @param in_elem Number of elements to allow. |
---|
304 | */ |
---|
305 | inline void set_size(const uword in_elem); |
---|
306 | |
---|
307 | /** |
---|
308 | * Set the size of the matrix |
---|
309 | * |
---|
310 | * @param in_rows Number of rows to allow. |
---|
311 | * @param in_cols Number of columns to allow. |
---|
312 | */ |
---|
313 | inline void set_size(const uword in_rows, const uword in_cols); |
---|
314 | |
---|
315 | inline void reshape(const uword in_rows, const uword in_cols, const uword dim = 0); |
---|
316 | |
---|
317 | inline const SpMat& zeros(); |
---|
318 | inline const SpMat& zeros(const uword in_elem); |
---|
319 | inline const SpMat& zeros(const uword in_rows, const uword in_cols); |
---|
320 | |
---|
321 | inline const SpMat& eye(); |
---|
322 | inline const SpMat& eye(const uword in_rows, const uword in_cols); |
---|
323 | |
---|
324 | inline const SpMat& speye(); |
---|
325 | inline const SpMat& speye(const uword in_rows, const uword in_cols); |
---|
326 | |
---|
327 | inline const SpMat& sprandu(const uword in_rows, const uword in_cols, const double density); |
---|
328 | |
---|
329 | inline const SpMat& sprandn(const uword in_rows, const uword in_cols, const double density); |
---|
330 | |
---|
331 | inline void reset(); |
---|
332 | |
---|
333 | |
---|
334 | // saving and loading |
---|
335 | |
---|
336 | inline bool save(const std::string name, const file_type type = arma_binary, const bool print_status = true) const; |
---|
337 | inline bool save( std::ostream& os, const file_type type = arma_binary, const bool print_status = true) const; |
---|
338 | |
---|
339 | inline bool load(const std::string name, const file_type type = arma_binary, const bool print_status = true); |
---|
340 | inline bool load( std::istream& is, const file_type type = arma_binary, const bool print_status = true); |
---|
341 | |
---|
342 | inline bool quiet_save(const std::string name, const file_type type = arma_binary) const; |
---|
343 | inline bool quiet_save( std::ostream& os, const file_type type = arma_binary) const; |
---|
344 | |
---|
345 | inline bool quiet_load(const std::string name, const file_type type = arma_binary); |
---|
346 | inline bool quiet_load( std::istream& is, const file_type type = arma_binary); |
---|
347 | |
---|
348 | // TODO: speed up loading of sparse matrices stored as text files (ie. raw_ascii and coord_ascii) |
---|
349 | // TODO: implement auto_detect for sparse matrices |
---|
350 | // TODO: modify docs to specify which formats are not applicable to sparse matrices |
---|
351 | |
---|
352 | |
---|
353 | // These forward declarations are necessary. |
---|
354 | class iterator_base; |
---|
355 | class iterator; |
---|
356 | class const_iterator; |
---|
357 | class row_iterator; |
---|
358 | class const_row_iterator; |
---|
359 | |
---|
360 | // Iterator base provides basic operators but not how to compare or how to |
---|
361 | // iterate. |
---|
362 | class iterator_base |
---|
363 | { |
---|
364 | public: |
---|
365 | |
---|
366 | inline iterator_base(); |
---|
367 | inline iterator_base(const SpMat& in_M); |
---|
368 | inline iterator_base(const SpMat& in_M, const uword col, const uword pos); |
---|
369 | |
---|
370 | inline arma_hot eT operator*() const; |
---|
371 | |
---|
372 | // Don't hold location internally; call "dummy" methods to get that information. |
---|
373 | arma_inline uword row() const { return M->row_indices[internal_pos]; } |
---|
374 | arma_inline uword col() const { return internal_col; } |
---|
375 | arma_inline uword pos() const { return internal_pos; } |
---|
376 | |
---|
377 | arma_aligned const SpMat* M; |
---|
378 | arma_aligned uword internal_col; |
---|
379 | arma_aligned uword internal_pos; |
---|
380 | |
---|
381 | // So that we satisfy the STL iterator types. |
---|
382 | typedef std::bidirectional_iterator_tag iterator_category; |
---|
383 | typedef eT value_type; |
---|
384 | typedef uword difference_type; // not certain on this one |
---|
385 | typedef const eT* pointer; |
---|
386 | typedef const eT& reference; |
---|
387 | }; |
---|
388 | |
---|
389 | class const_iterator : public iterator_base |
---|
390 | { |
---|
391 | public: |
---|
392 | |
---|
393 | inline const_iterator(); |
---|
394 | inline const_iterator(const SpMat& in_M, uword initial_pos = 0); // Assumes initial_pos is valid. |
---|
395 | //! Once initialized, will be at the first nonzero value after the given position (using forward columnwise traversal). |
---|
396 | inline const_iterator(const SpMat& in_M, uword in_row, uword in_col); |
---|
397 | //! If you know the exact position of the iterator. in_row is a dummy argument. |
---|
398 | inline const_iterator(const SpMat& in_M, uword in_row, uword in_col, uword in_pos); |
---|
399 | inline const_iterator(const const_iterator& other); |
---|
400 | |
---|
401 | inline arma_hot const_iterator& operator++(); |
---|
402 | inline arma_hot const_iterator operator++(int); |
---|
403 | |
---|
404 | inline arma_hot const_iterator& operator--(); |
---|
405 | inline arma_hot const_iterator operator--(int); |
---|
406 | |
---|
407 | inline arma_hot bool operator==(const const_iterator& rhs) const; |
---|
408 | inline arma_hot bool operator!=(const const_iterator& rhs) const; |
---|
409 | |
---|
410 | inline arma_hot bool operator==(const typename SpSubview<eT>::const_iterator& rhs) const; |
---|
411 | inline arma_hot bool operator!=(const typename SpSubview<eT>::const_iterator& rhs) const; |
---|
412 | |
---|
413 | inline arma_hot bool operator==(const const_row_iterator& rhs) const; |
---|
414 | inline arma_hot bool operator!=(const const_row_iterator& rhs) const; |
---|
415 | |
---|
416 | inline arma_hot bool operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const; |
---|
417 | inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const; |
---|
418 | }; |
---|
419 | |
---|
420 | /** |
---|
421 | * So that we can iterate over nonzero values, we need an iterator |
---|
422 | * implementation. This can't be as simple as Mat's, which is just a pointer |
---|
423 | * to an eT. If a value is set to 0 using this iterator, the iterator is no |
---|
424 | * longer valid! |
---|
425 | */ |
---|
426 | class iterator : public const_iterator |
---|
427 | { |
---|
428 | public: |
---|
429 | |
---|
430 | inline iterator() : const_iterator() { } |
---|
431 | inline iterator(SpMat& in_M, uword initial_pos = 0) : const_iterator(in_M, initial_pos) { } |
---|
432 | inline iterator(SpMat& in_M, uword in_row, uword in_col) : const_iterator(in_M, in_row, in_col) { } |
---|
433 | inline iterator(SpMat& in_M, uword in_row, uword in_col, uword in_pos) : const_iterator(in_M, in_row, in_col, in_pos) { } |
---|
434 | inline iterator(const const_iterator& other) : const_iterator(other) { } |
---|
435 | |
---|
436 | inline arma_hot SpValProxy<SpMat<eT> > operator*(); |
---|
437 | |
---|
438 | // overloads needed for return type correctness |
---|
439 | inline arma_hot iterator& operator++(); |
---|
440 | inline arma_hot iterator operator++(int); |
---|
441 | |
---|
442 | inline arma_hot iterator& operator--(); |
---|
443 | inline arma_hot iterator operator--(int); |
---|
444 | |
---|
445 | // This has a different value_type than iterator_base. |
---|
446 | typedef SpValProxy<SpMat<eT> > value_type; |
---|
447 | typedef const SpValProxy<SpMat<eT> >* pointer; |
---|
448 | typedef const SpValProxy<SpMat<eT> >& reference; |
---|
449 | }; |
---|
450 | |
---|
451 | class const_row_iterator : public iterator_base |
---|
452 | { |
---|
453 | public: |
---|
454 | |
---|
455 | inline const_row_iterator(); |
---|
456 | inline const_row_iterator(const SpMat& in_M, uword initial_pos = 0); |
---|
457 | //! Once initialized, will be at the first nonzero value after the given position (using forward row-wise traversal). |
---|
458 | inline const_row_iterator(const SpMat& in_M, uword in_row, uword in_col); |
---|
459 | inline const_row_iterator(const const_row_iterator& other); |
---|
460 | |
---|
461 | inline arma_hot const_row_iterator& operator++(); |
---|
462 | inline arma_hot const_row_iterator operator++(int); |
---|
463 | |
---|
464 | inline arma_hot const_row_iterator& operator--(); |
---|
465 | inline arma_hot const_row_iterator operator--(int); |
---|
466 | |
---|
467 | uword internal_row; // Hold row internally because we use internal_pos differently. |
---|
468 | uword actual_pos; // Actual position in matrix. |
---|
469 | |
---|
470 | arma_inline eT operator*() const { return iterator_base::M->values[actual_pos]; } |
---|
471 | |
---|
472 | arma_inline uword row() const { return internal_row; } |
---|
473 | |
---|
474 | inline arma_hot bool operator==(const const_iterator& rhs) const; |
---|
475 | inline arma_hot bool operator!=(const const_iterator& rhs) const; |
---|
476 | |
---|
477 | inline arma_hot bool operator==(const typename SpSubview<eT>::const_iterator& rhs) const; |
---|
478 | inline arma_hot bool operator!=(const typename SpSubview<eT>::const_iterator& rhs) const; |
---|
479 | |
---|
480 | inline arma_hot bool operator==(const const_row_iterator& rhs) const; |
---|
481 | inline arma_hot bool operator!=(const const_row_iterator& rhs) const; |
---|
482 | |
---|
483 | inline arma_hot bool operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const; |
---|
484 | inline arma_hot bool operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const; |
---|
485 | }; |
---|
486 | |
---|
487 | class row_iterator : public const_row_iterator |
---|
488 | { |
---|
489 | public: |
---|
490 | |
---|
491 | inline row_iterator() : const_row_iterator() {} |
---|
492 | inline row_iterator(SpMat& in_M, uword initial_pos = 0) : const_row_iterator(in_M, initial_pos) { } |
---|
493 | //! Once initialized, will be at the first nonzero value after the given position (using forward row-wise traversal). |
---|
494 | inline row_iterator(SpMat& in_M, uword in_row, uword in_col) : const_row_iterator(in_M, in_row, in_col) { } |
---|
495 | inline row_iterator(const row_iterator& other) : const_row_iterator(other) { } |
---|
496 | |
---|
497 | inline arma_hot SpValProxy<SpMat<eT> > operator*(); |
---|
498 | |
---|
499 | // overloads required for return type correctness |
---|
500 | inline arma_hot row_iterator& operator++(); |
---|
501 | inline arma_hot row_iterator operator++(int); |
---|
502 | |
---|
503 | inline arma_hot row_iterator& operator--(); |
---|
504 | inline arma_hot row_iterator operator--(int); |
---|
505 | |
---|
506 | // This has a different value_type than iterator_base. |
---|
507 | typedef SpValProxy<SpMat<eT> > value_type; |
---|
508 | typedef const SpValProxy<SpMat<eT> >* pointer; |
---|
509 | typedef const SpValProxy<SpMat<eT> >& reference; |
---|
510 | }; |
---|
511 | |
---|
512 | |
---|
513 | typedef iterator row_col_iterator; |
---|
514 | typedef const_iterator const_row_col_iterator; |
---|
515 | |
---|
516 | |
---|
517 | inline iterator begin(); |
---|
518 | inline const_iterator begin() const; |
---|
519 | |
---|
520 | inline iterator end(); |
---|
521 | inline const_iterator end() const; |
---|
522 | |
---|
523 | inline iterator begin_col(const uword col_num); |
---|
524 | inline const_iterator begin_col(const uword col_num) const; |
---|
525 | |
---|
526 | inline iterator end_col(const uword col_num); |
---|
527 | inline const_iterator end_col(const uword col_num) const; |
---|
528 | |
---|
529 | inline row_iterator begin_row(const uword row_num = 0); |
---|
530 | inline const_row_iterator begin_row(const uword row_num = 0) const; |
---|
531 | |
---|
532 | inline row_iterator end_row(); |
---|
533 | inline const_row_iterator end_row() const; |
---|
534 | |
---|
535 | inline row_iterator end_row(const uword row_num); |
---|
536 | inline const_row_iterator end_row(const uword row_num) const; |
---|
537 | |
---|
538 | inline row_col_iterator begin_row_col(); |
---|
539 | inline const_row_col_iterator begin_row_col() const; |
---|
540 | |
---|
541 | inline row_col_iterator end_row_col(); |
---|
542 | inline const_row_col_iterator end_row_col() const; |
---|
543 | |
---|
544 | |
---|
545 | inline void clear(); |
---|
546 | inline bool empty() const; |
---|
547 | inline uword size() const; |
---|
548 | |
---|
549 | /** |
---|
550 | * Resize memory. You are responsible for updating the column pointers and |
---|
551 | * filling the new memory (if the new size is larger). If the new size is |
---|
552 | * smaller, the first new_n_nonzero elements will be copied. n_nonzero is |
---|
553 | * updated. |
---|
554 | */ |
---|
555 | inline void mem_resize(const uword new_n_nonzero); |
---|
556 | |
---|
557 | //! don't use this unless you're writing internal Armadillo code |
---|
558 | inline void remove_zeros(); |
---|
559 | |
---|
560 | //! don't use this unless you're writing internal Armadillo code |
---|
561 | inline void steal_mem(SpMat& X); |
---|
562 | |
---|
563 | //! don't use this unless you're writing internal Armadillo code |
---|
564 | template< typename T1, typename Functor> arma_hot inline void init_xform (const SpBase<eT, T1>& x, const Functor& func); |
---|
565 | template<typename eT2, typename T1, typename Functor> arma_hot inline void init_xform_mt(const SpBase<eT2,T1>& x, const Functor& func); |
---|
566 | |
---|
567 | |
---|
568 | protected: |
---|
569 | |
---|
570 | /** |
---|
571 | * Initialize the matrix to the specified size. Data is not preserved, so the matrix is assumed to be entirely sparse (empty). |
---|
572 | */ |
---|
573 | inline void init(uword in_rows, uword in_cols); |
---|
574 | |
---|
575 | /** |
---|
576 | * Initialize the matrix from text. Data is (of course) not preserved, and |
---|
577 | * the size will be reset. |
---|
578 | */ |
---|
579 | inline void init(const std::string& text); |
---|
580 | |
---|
581 | /** |
---|
582 | * Initialize from another matrix (copy). |
---|
583 | */ |
---|
584 | inline void init(const SpMat& x); |
---|
585 | |
---|
586 | |
---|
587 | inline void init_batch_std(const Mat<uword>& locations, const Mat<eT>& values, const bool sort_locations); |
---|
588 | inline void init_batch_add(const Mat<uword>& locations, const Mat<eT>& values, const bool sort_locations); |
---|
589 | |
---|
590 | |
---|
591 | |
---|
592 | private: |
---|
593 | |
---|
594 | /** |
---|
595 | * Return the given element. |
---|
596 | */ |
---|
597 | inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const uword i); |
---|
598 | inline arma_hot arma_warn_unused eT get_value(const uword i) const; |
---|
599 | |
---|
600 | inline arma_hot arma_warn_unused SpValProxy<SpMat<eT> > get_value(const uword in_row, const uword in_col); |
---|
601 | inline arma_hot arma_warn_unused eT get_value(const uword in_row, const uword in_col) const; |
---|
602 | |
---|
603 | /** |
---|
604 | * Given the index representing which of the nonzero values this is, return |
---|
605 | * its actual location, either in row/col or just the index. |
---|
606 | */ |
---|
607 | arma_inline arma_hot arma_warn_unused uword get_position(const uword i) const; |
---|
608 | arma_inline arma_hot void get_position(const uword i, uword& row_of_i, uword& col_of_i) const; |
---|
609 | |
---|
610 | /** |
---|
611 | * Add an element at the given position, and return a reference to it. The |
---|
612 | * element will be set to 0 (unless otherwise specified). If the element |
---|
613 | * already exists, its value will be overwritten. |
---|
614 | * |
---|
615 | * @param in_row Row of new element. |
---|
616 | * @param in_col Column of new element. |
---|
617 | * @param in_val Value to set new element to (default 0.0). |
---|
618 | */ |
---|
619 | inline arma_hot arma_warn_unused eT& add_element(const uword in_row, const uword in_col, const eT in_val = 0.0); |
---|
620 | |
---|
621 | /** |
---|
622 | * Delete an element at the given position. |
---|
623 | * |
---|
624 | * @param in_row Row of element to be deleted. |
---|
625 | * @param in_col Column of element to be deleted. |
---|
626 | */ |
---|
627 | inline arma_hot void delete_element(const uword in_row, const uword in_col); |
---|
628 | |
---|
629 | |
---|
630 | public: |
---|
631 | |
---|
632 | #ifdef ARMA_EXTRA_SPMAT_PROTO |
---|
633 | #include ARMA_INCFILE_WRAP(ARMA_EXTRA_SPMAT_PROTO) |
---|
634 | #endif |
---|
635 | }; |
---|
636 | |
---|
637 | |
---|
638 | |
---|
639 | #define ARMA_HAS_SPMAT |
---|
640 | |
---|
641 | |
---|
642 | |
---|
643 | //! @} |
---|