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