Mercurial > hg > octave-lyh
annotate liboctave/Sparse.h @ 7820:cb4838d70ab2
Fix default value for axes gridlinestyle and minorgridlinestyle.
author | Michael Goffioul <michael.goffioul@gmail.com> |
---|---|
date | Thu, 07 Feb 2008 16:21:03 +0100 |
parents | ff918ee1a983 |
children | 1ebcb9872ced |
rev | line source |
---|---|
5164 | 1 // Template sparse classes |
2 /* | |
3 | |
7017 | 4 Copyright (C) 2004, 2005, 2006, 2007 David Bateman |
7016 | 5 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Andy Adler |
6 | |
7 This file is part of Octave. | |
5164 | 8 |
9 Octave is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
7016 | 11 Free Software Foundation; either version 3 of the License, or (at your |
12 option) any later version. | |
5164 | 13 |
14 Octave is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
7016 | 20 along with Octave; see the file COPYING. If not, see |
21 <http://www.gnu.org/licenses/>. | |
5164 | 22 |
23 */ | |
24 | |
25 #if !defined (octave_Sparse_h) | |
26 #define octave_Sparse_h 1 | |
27 | |
28 #include <cassert> | |
29 #include <cstddef> | |
30 | |
31 #include <iostream> | |
32 | |
33 #include "Array.h" | |
34 #include "Array2.h" | |
35 #include "dim-vector.h" | |
36 #include "lo-utils.h" | |
37 | |
7433 | 38 #include "oct-sort.h" |
39 | |
5164 | 40 class idx_vector; |
41 | |
42 // Two dimensional sparse class. Handles the reference counting for | |
43 // all the derived classes. | |
44 | |
45 template <class T> | |
46 class | |
47 Sparse | |
48 { | |
49 protected: | |
50 //-------------------------------------------------------------------- | |
51 // The real representation of all Sparse arrays. | |
52 //-------------------------------------------------------------------- | |
53 | |
6108 | 54 class OCTAVE_API SparseRep |
5164 | 55 { |
56 public: | |
57 | |
58 T *d; | |
5275 | 59 octave_idx_type *r; |
60 octave_idx_type *c; | |
5604 | 61 octave_idx_type nzmx; |
5275 | 62 octave_idx_type nrows; |
63 octave_idx_type ncols; | |
5164 | 64 int count; |
65 | |
5604 | 66 SparseRep (void) : d (0), r (0), c (new octave_idx_type [1]), nzmx (0), nrows (0), |
5164 | 67 ncols (0), count (1) { c[0] = 0; } |
68 | |
5604 | 69 SparseRep (octave_idx_type n) : d (0), r (0), c (new octave_idx_type [n+1]), nzmx (0), nrows (n), |
5164 | 70 ncols (n), count (1) |
71 { | |
5275 | 72 for (octave_idx_type i = 0; i < n + 1; i++) |
5164 | 73 c[i] = 0; |
74 } | |
75 | |
5604 | 76 SparseRep (octave_idx_type nr, octave_idx_type nc) : d (0), r (0), c (new octave_idx_type [nc+1]), nzmx (0), |
5164 | 77 nrows (nr), ncols (nc), count (1) |
78 { | |
5275 | 79 for (octave_idx_type i = 0; i < nc + 1; i++) |
5164 | 80 c[i] = 0; |
81 } | |
82 | |
5275 | 83 SparseRep (octave_idx_type nr, octave_idx_type nc, octave_idx_type nz) : d (new T [nz]), |
5604 | 84 r (new octave_idx_type [nz]), c (new octave_idx_type [nc+1]), nzmx (nz), nrows (nr), |
5164 | 85 ncols (nc), count (1) |
86 { | |
5275 | 87 for (octave_idx_type i = 0; i < nc + 1; i++) |
5164 | 88 c[i] = 0; |
89 } | |
90 | |
91 SparseRep (const SparseRep& a) | |
5604 | 92 : d (new T [a.nzmx]), r (new octave_idx_type [a.nzmx]), c (new octave_idx_type [a.ncols + 1]), |
93 nzmx (a.nzmx), nrows (a.nrows), ncols (a.ncols), count (1) | |
5164 | 94 { |
5604 | 95 for (octave_idx_type i = 0; i < nzmx; i++) |
5164 | 96 { |
97 d[i] = a.d[i]; | |
98 r[i] = a.r[i]; | |
99 } | |
5275 | 100 for (octave_idx_type i = 0; i < ncols + 1; i++) |
5164 | 101 c[i] = a.c[i]; |
102 } | |
103 | |
104 ~SparseRep (void) { delete [] d; delete [] r; delete [] c; } | |
105 | |
5604 | 106 octave_idx_type length (void) const { return nzmx; } |
5164 | 107 |
5604 | 108 octave_idx_type nnz (void) const { return c [ncols]; } |
5164 | 109 |
5275 | 110 T& elem (octave_idx_type _r, octave_idx_type _c); |
5164 | 111 |
5275 | 112 T celem (octave_idx_type _r, octave_idx_type _c) const; |
5164 | 113 |
5275 | 114 T& data (octave_idx_type i) { return d[i]; } |
5164 | 115 |
5275 | 116 T cdata (octave_idx_type i) const { return d[i]; } |
5164 | 117 |
5275 | 118 octave_idx_type& ridx (octave_idx_type i) { return r[i]; } |
5164 | 119 |
5275 | 120 octave_idx_type cridx (octave_idx_type i) const { return r[i]; } |
5164 | 121 |
5275 | 122 octave_idx_type& cidx (octave_idx_type i) { return c[i]; } |
5164 | 123 |
5275 | 124 octave_idx_type ccidx (octave_idx_type i) const { return c[i]; } |
5164 | 125 |
126 void maybe_compress (bool remove_zeros); | |
127 | |
5275 | 128 void change_length (octave_idx_type nz); |
5164 | 129 |
130 private: | |
131 | |
132 // No assignment! | |
133 | |
134 SparseRep& operator = (const SparseRep& a); | |
135 }; | |
136 | |
137 //-------------------------------------------------------------------- | |
138 | |
139 void make_unique (void) | |
140 { | |
141 if (rep->count > 1) | |
142 { | |
143 --rep->count; | |
144 rep = new SparseRep (*rep); | |
145 } | |
146 } | |
147 | |
148 public: | |
149 | |
150 // !!! WARNING !!! -- these should be protected, not public. You | |
151 // should not access these data members directly! | |
152 | |
153 typename Sparse<T>::SparseRep *rep; | |
154 | |
155 dim_vector dimensions; | |
156 | |
157 protected: | |
158 idx_vector *idx; | |
5275 | 159 octave_idx_type idx_count; |
5164 | 160 |
161 private: | |
162 | |
163 typename Sparse<T>::SparseRep *nil_rep (void) const | |
164 { | |
165 static typename Sparse<T>::SparseRep *nr | |
166 = new typename Sparse<T>::SparseRep (); | |
167 | |
168 nr->count++; | |
169 | |
170 return nr; | |
171 } | |
172 | |
173 public: | |
174 | |
175 Sparse (void) | |
176 : rep (nil_rep ()), dimensions (dim_vector(0,0)), | |
177 idx (0), idx_count (0) { } | |
178 | |
5275 | 179 explicit Sparse (octave_idx_type n) |
5164 | 180 : rep (new typename Sparse<T>::SparseRep (n)), |
181 dimensions (dim_vector (n, n)), idx (0), idx_count (0) { } | |
182 | |
5275 | 183 explicit Sparse (octave_idx_type nr, octave_idx_type nc) |
5164 | 184 : rep (new typename Sparse<T>::SparseRep (nr, nc)), |
185 dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) { } | |
186 | |
5275 | 187 explicit Sparse (octave_idx_type nr, octave_idx_type nc, T val); |
5164 | 188 |
5275 | 189 Sparse (const dim_vector& dv, octave_idx_type nz) |
5164 | 190 : rep (new typename Sparse<T>::SparseRep (dv(0), dv(1), nz)), |
191 dimensions (dv), idx (0), idx_count (0) { } | |
192 | |
5275 | 193 Sparse (octave_idx_type nr, octave_idx_type nc, octave_idx_type nz) |
5164 | 194 : rep (new typename Sparse<T>::SparseRep (nr, nc, nz)), |
195 dimensions (dim_vector (nr, nc)), idx (0), idx_count (0) { } | |
196 | |
197 // Type conversion case. | |
198 template <class U> Sparse (const Sparse<U>& a); | |
199 | |
200 // No type conversion case. | |
201 Sparse (const Sparse<T>& a) | |
202 : rep (a.rep), dimensions (a.dimensions), idx (0), idx_count (0) | |
203 { | |
204 rep->count++; | |
205 } | |
206 | |
207 public: | |
208 | |
209 Sparse (const dim_vector& dv); | |
210 | |
211 Sparse (const Sparse<T>& a, const dim_vector& dv); | |
212 | |
5275 | 213 Sparse (const Array<T>& a, const Array<octave_idx_type>& r, const Array<octave_idx_type>& c, |
214 octave_idx_type nr, octave_idx_type nc, bool sum_terms); | |
5164 | 215 |
216 Sparse (const Array<T>& a, const Array<double>& r, const Array<double>& c, | |
5275 | 217 octave_idx_type nr, octave_idx_type nc, bool sum_terms); |
5164 | 218 |
219 // Sparsify a normal matrix | |
220 Sparse (const Array2<T>& a); | |
221 Sparse (const Array<T>& a); | |
222 | |
223 virtual ~Sparse (void); | |
224 | |
7717
ff918ee1a983
Delete idx in Sparse<T> and Array<T> operator =
David Bateman <dbateman@free.fr>
parents:
7620
diff
changeset
|
225 Sparse<T>& operator = (const Sparse<T>& a); |
5164 | 226 |
5604 | 227 // Note that nzmax and capacity are the amount of storage for |
228 // non-zero elements, while nnz is the actual number of non-zero | |
229 // terms. | |
230 octave_idx_type nzmax (void) const { return rep->length (); } | |
231 octave_idx_type capacity (void) const { return nzmax (); } | |
232 octave_idx_type nnz (void) const { return rep->nnz (); } | |
5164 | 233 |
234 // Paranoid number of elements test for case of dims = (-1,-1) | |
5275 | 235 octave_idx_type numel (void) const |
5164 | 236 { |
237 if (dim1() < 0 || dim2() < 0) | |
238 return 0; | |
239 else | |
240 return dimensions.numel (); | |
241 } | |
242 | |
5275 | 243 octave_idx_type nelem (void) const { return capacity (); } |
244 octave_idx_type length (void) const { return numel (); } | |
5164 | 245 |
5275 | 246 octave_idx_type dim1 (void) const { return dimensions(0); } |
247 octave_idx_type dim2 (void) const { return dimensions(1); } | |
5164 | 248 |
5275 | 249 octave_idx_type rows (void) const { return dim1 (); } |
250 octave_idx_type cols (void) const { return dim2 (); } | |
251 octave_idx_type columns (void) const { return dim2 (); } | |
5164 | 252 |
5275 | 253 octave_idx_type get_row_index (octave_idx_type k) { return ridx (k); } |
254 octave_idx_type get_col_index (octave_idx_type k) | |
5164 | 255 { |
5275 | 256 octave_idx_type ret = 0; |
5164 | 257 while (cidx(ret+1) < k) |
258 ret++; | |
259 return ret; | |
260 } | |
5275 | 261 size_t byte_size (void) const { return (cols () + 1) * sizeof (octave_idx_type) + |
262 capacity () * (sizeof (T) + sizeof (octave_idx_type)); } | |
5164 | 263 |
264 dim_vector dims (void) const { return dimensions; } | |
265 | |
266 Sparse<T> squeeze (void) const { return *this; } | |
267 | |
5275 | 268 octave_idx_type compute_index (const Array<octave_idx_type>& ra_idx) const; |
5164 | 269 |
5275 | 270 T range_error (const char *fcn, octave_idx_type n) const; |
271 T& range_error (const char *fcn, octave_idx_type n); | |
5164 | 272 |
5275 | 273 T range_error (const char *fcn, octave_idx_type i, octave_idx_type j) const; |
274 T& range_error (const char *fcn, octave_idx_type i, octave_idx_type j); | |
5164 | 275 |
5275 | 276 T range_error (const char *fcn, const Array<octave_idx_type>& ra_idx) const; |
277 T& range_error (const char *fcn, const Array<octave_idx_type>& ra_idx); | |
5164 | 278 |
279 // No checking, even for multiple references, ever. | |
280 | |
5275 | 281 T& xelem (octave_idx_type n) |
5164 | 282 { |
5275 | 283 octave_idx_type i = n % rows (), j = n / rows(); |
5164 | 284 return xelem (i, j); |
285 } | |
286 | |
5275 | 287 T xelem (octave_idx_type n) const |
5164 | 288 { |
5275 | 289 octave_idx_type i = n % rows (), j = n / rows(); |
5164 | 290 return xelem (i, j); |
291 } | |
292 | |
5275 | 293 T& xelem (octave_idx_type i, octave_idx_type j) { return rep->elem (i, j); } |
294 T xelem (octave_idx_type i, octave_idx_type j) const { return rep->celem (i, j); } | |
5164 | 295 |
5275 | 296 T& xelem (const Array<octave_idx_type>& ra_idx) |
5164 | 297 { return xelem (compute_index (ra_idx)); } |
298 | |
5275 | 299 T xelem (const Array<octave_idx_type>& ra_idx) const |
5164 | 300 { return xelem (compute_index (ra_idx)); } |
301 | |
5775 | 302 // FIXME -- would be nice to fix this so that we don't |
5164 | 303 // unnecessarily force a copy, but that is not so easy, and I see no |
304 // clean way to do it. | |
305 | |
5275 | 306 T& checkelem (octave_idx_type n) |
5164 | 307 { |
308 if (n < 0 || n >= numel ()) | |
309 return range_error ("T& Sparse<T>::checkelem", n); | |
310 else | |
311 { | |
312 make_unique (); | |
313 return xelem (n); | |
314 } | |
315 } | |
316 | |
5275 | 317 T& checkelem (octave_idx_type i, octave_idx_type j) |
5164 | 318 { |
319 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ()) | |
320 return range_error ("T& Sparse<T>::checkelem", i, j); | |
321 else | |
322 { | |
323 make_unique (); | |
324 return xelem (i, j); | |
325 } | |
326 } | |
327 | |
5275 | 328 T& checkelem (const Array<octave_idx_type>& ra_idx) |
5164 | 329 { |
5275 | 330 octave_idx_type i = compute_index (ra_idx); |
5164 | 331 |
332 if (i < 0) | |
333 return range_error ("T& Sparse<T>::checkelem", ra_idx); | |
334 else | |
335 return elem (i); | |
336 } | |
337 | |
5275 | 338 T& elem (octave_idx_type n) |
5164 | 339 { |
340 make_unique (); | |
341 return xelem (n); | |
342 } | |
343 | |
5275 | 344 T& elem (octave_idx_type i, octave_idx_type j) |
5164 | 345 { |
346 make_unique (); | |
347 return xelem (i, j); | |
348 } | |
349 | |
5275 | 350 T& elem (const Array<octave_idx_type>& ra_idx) |
5164 | 351 { return Sparse<T>::elem (compute_index (ra_idx)); } |
352 | |
353 #if defined (BOUNDS_CHECKING) | |
5275 | 354 T& operator () (octave_idx_type n) { return checkelem (n); } |
355 T& operator () (octave_idx_type i, octave_idx_type j) { return checkelem (i, j); } | |
356 T& operator () (const Array<octave_idx_type>& ra_idx) { return checkelem (ra_idx); } | |
5164 | 357 #else |
5275 | 358 T& operator () (octave_idx_type n) { return elem (n); } |
359 T& operator () (octave_idx_type i, octave_idx_type j) { return elem (i, j); } | |
360 T& operator () (const Array<octave_idx_type>& ra_idx) { return elem (ra_idx); } | |
5164 | 361 #endif |
362 | |
5275 | 363 T checkelem (octave_idx_type n) const |
5164 | 364 { |
365 if (n < 0 || n >= numel ()) | |
366 return range_error ("T Sparse<T>::checkelem", n); | |
367 else | |
368 return xelem (n); | |
369 } | |
370 | |
5275 | 371 T checkelem (octave_idx_type i, octave_idx_type j) const |
5164 | 372 { |
373 if (i < 0 || j < 0 || i >= dim1 () || j >= dim2 ()) | |
374 return range_error ("T Sparse<T>::checkelem", i, j); | |
375 else | |
376 return xelem (i, j); | |
377 } | |
378 | |
5275 | 379 T checkelem (const Array<octave_idx_type>& ra_idx) const |
5164 | 380 { |
5275 | 381 octave_idx_type i = compute_index (ra_idx); |
5164 | 382 |
383 if (i < 0) | |
384 return range_error ("T Sparse<T>::checkelem", ra_idx); | |
385 else | |
386 return Sparse<T>::elem (i); | |
387 } | |
388 | |
5275 | 389 T elem (octave_idx_type n) const { return xelem (n); } |
5164 | 390 |
5275 | 391 T elem (octave_idx_type i, octave_idx_type j) const { return xelem (i, j); } |
5164 | 392 |
5275 | 393 T elem (const Array<octave_idx_type>& ra_idx) const |
5164 | 394 { return Sparse<T>::elem (compute_index (ra_idx)); } |
395 | |
396 #if defined (BOUNDS_CHECKING) | |
5275 | 397 T operator () (octave_idx_type n) const { return checkelem (n); } |
398 T operator () (octave_idx_type i, octave_idx_type j) const { return checkelem (i, j); } | |
399 T operator () (const Array<octave_idx_type>& ra_idx) const { return checkelem (ra_idx); } | |
5164 | 400 #else |
5275 | 401 T operator () (octave_idx_type n) const { return elem (n); } |
402 T operator () (octave_idx_type i, octave_idx_type j) const { return elem (i, j); } | |
403 T operator () (const Array<octave_idx_type>& ra_idx) const { return elem (ra_idx); } | |
5164 | 404 #endif |
405 | |
406 Sparse<T> maybe_compress (bool remove_zeros = false) | |
407 { rep->maybe_compress (remove_zeros); return (*this); } | |
408 | |
409 Sparse<T> reshape (const dim_vector& new_dims) const; | |
410 | |
411 // !!! WARNING !!! -- the following resize_no_fill functions are | |
412 // public because template friends don't work properly with versions | |
413 // of gcc earlier than 3.3. You should use these functions only in | |
414 // classes that are derived from Sparse<T>. | |
415 | |
416 // protected: | |
417 | |
5275 | 418 void resize_no_fill (octave_idx_type r, octave_idx_type c); |
5164 | 419 |
420 void resize_no_fill (const dim_vector& dv); | |
421 | |
422 public: | |
5275 | 423 Sparse<T> permute (const Array<octave_idx_type>& vec, bool inv = false) const; |
5164 | 424 |
5275 | 425 Sparse<T> ipermute (const Array<octave_idx_type>& vec) const |
5164 | 426 { return permute (vec, true); } |
427 | |
5275 | 428 void resize (octave_idx_type r, octave_idx_type c) { resize_no_fill (r, c); } |
5164 | 429 |
430 void resize (const dim_vector& dv) { resize_no_fill (dv); } | |
431 | |
5275 | 432 void change_capacity (octave_idx_type nz) { rep->change_length (nz); } |
5164 | 433 |
5275 | 434 Sparse<T>& insert (const Sparse<T>& a, octave_idx_type r, octave_idx_type c); |
435 Sparse<T>& insert (const Sparse<T>& a, const Array<octave_idx_type>& idx); | |
5164 | 436 |
437 bool is_square (void) const { return (dim1 () == dim2 ()); } | |
438 | |
439 bool is_empty (void) const { return (rows () < 1 && cols () < 1); } | |
440 | |
441 Sparse<T> transpose (void) const; | |
442 | |
443 T* data (void) { make_unique (); return rep->d; } | |
5275 | 444 T& data (octave_idx_type i) { make_unique (); return rep->data (i); } |
5164 | 445 T* xdata (void) { return rep->d; } |
5275 | 446 T& xdata (octave_idx_type i) { return rep->data (i); } |
5164 | 447 |
5275 | 448 T data (octave_idx_type i) const { return rep->data (i); } |
5900 | 449 // FIXME -- shouldn't this be returning const T*? |
5164 | 450 T* data (void) const { return rep->d; } |
451 | |
5275 | 452 octave_idx_type* ridx (void) { make_unique (); return rep->r; } |
453 octave_idx_type& ridx (octave_idx_type i) { make_unique (); return rep->ridx (i); } | |
454 octave_idx_type* xridx (void) { return rep->r; } | |
455 octave_idx_type& xridx (octave_idx_type i) { return rep->ridx (i); } | |
5164 | 456 |
5275 | 457 octave_idx_type ridx (octave_idx_type i) const { return rep->cridx (i); } |
5900 | 458 // FIXME -- shouldn't this be returning const octave_idx_type*? |
5275 | 459 octave_idx_type* ridx (void) const { return rep->r; } |
5164 | 460 |
5275 | 461 octave_idx_type* cidx (void) { make_unique (); return rep->c; } |
462 octave_idx_type& cidx (octave_idx_type i) { make_unique (); return rep->cidx (i); } | |
463 octave_idx_type* xcidx (void) { return rep->c; } | |
464 octave_idx_type& xcidx (octave_idx_type i) { return rep->cidx (i); } | |
5164 | 465 |
5275 | 466 octave_idx_type cidx (octave_idx_type i) const { return rep->ccidx (i); } |
5900 | 467 // FIXME -- shouldn't this be returning const octave_idx_type*? |
5275 | 468 octave_idx_type* cidx (void) const { return rep->c; } |
5164 | 469 |
5275 | 470 octave_idx_type ndims (void) const { return dimensions.length (); } |
5164 | 471 |
472 void clear_index (void); | |
473 | |
474 void set_index (const idx_vector& i); | |
475 | |
5275 | 476 octave_idx_type index_count (void) const { return idx_count; } |
5164 | 477 |
478 idx_vector *get_idx (void) const { return idx; } | |
479 | |
480 void maybe_delete_elements (idx_vector& i); | |
481 | |
482 void maybe_delete_elements (idx_vector& i, idx_vector& j); | |
483 | |
484 void maybe_delete_elements (Array<idx_vector>& ra_idx); | |
485 | |
486 Sparse<T> value (void); | |
487 | |
488 Sparse<T> index (idx_vector& i, int resize_ok = 0) const; | |
489 | |
490 Sparse<T> index (idx_vector& i, idx_vector& j, int resize_ok = 0) const; | |
491 | |
492 Sparse<T> index (Array<idx_vector>& ra_idx, int resize_ok = 0) const; | |
493 | |
494 void print_info (std::ostream& os, const std::string& prefix) const; | |
495 | |
5900 | 496 // Unsafe. These functions exist to support the MEX interface. |
497 // You should not use them anywhere else. | |
498 void *mex_get_data (void) const { return const_cast<T *> (data ()); } | |
499 | |
500 octave_idx_type *mex_get_ir (void) const { return const_cast<octave_idx_type *> (ridx ()); } | |
501 | |
502 octave_idx_type *mex_get_jc (void) const { return const_cast<octave_idx_type *> (cidx ()); } | |
7433 | 503 |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
504 Sparse<T> sort (octave_idx_type dim = 0, sortmode mode = ASCENDING) const; |
7433 | 505 Sparse<T> sort (Array<octave_idx_type> &sidx, octave_idx_type dim = 0, |
7463
2467639bd8c0
eliminate UNDEFINED sort mode
John W. Eaton <jwe@octave.org>
parents:
7433
diff
changeset
|
506 sortmode mode = ASCENDING) const; |
7602
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
507 |
7620
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7602
diff
changeset
|
508 Sparse<T> diag (octave_idx_type k = 0) const; |
36594d5bbe13
Move diag function into the octave_value class
David Bateman <dbateman@free.fr>
parents:
7602
diff
changeset
|
509 |
7602
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
510 template <class U, class F> |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
511 Sparse<U> |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
512 map (F fcn) const |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
513 { |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
514 Sparse<U> result; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
515 U f_zero = fcn (0.); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
516 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
517 if (f_zero != 0.) |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
518 { |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
519 octave_idx_type nr = rows (); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
520 octave_idx_type nc = cols (); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
521 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
522 result = Sparse<U> (nr, nc, f_zero); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
523 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
524 for (octave_idx_type j = 0; j < nc; j++) |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
525 for (octave_idx_type i = cidx(j); i < cidx (j+1); i++) |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
526 { |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
527 OCTAVE_QUIT; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
528 /* Use data instead of elem for better performance. */ |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
529 result.data (ridx (i) + j * nr) = fcn (data(i)); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
530 } |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
531 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
532 result.maybe_compress (true); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
533 } |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
534 else |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
535 { |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
536 octave_idx_type nz = nnz (); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
537 octave_idx_type nr = rows (); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
538 octave_idx_type nc = cols (); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
539 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
540 result = Sparse<U> (nr, nc, nz); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
541 octave_idx_type ii = 0; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
542 result.cidx (ii) = 0; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
543 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
544 for (octave_idx_type j = 0; j < nc; j++) |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
545 { |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
546 for (octave_idx_type i = cidx(j); i < cidx (j+1); i++) |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
547 { |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
548 U val = fcn (data (i)); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
549 if (val != 0.0) |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
550 { |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
551 result.data (ii) = val; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
552 result.ridx (ii++) = ridx (i); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
553 } |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
554 OCTAVE_QUIT; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
555 } |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
556 result.cidx (j+1) = ii; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
557 } |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
558 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
559 result.maybe_compress (false); |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
560 } |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
561 |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
562 return result; |
7bfaa9611558
Rewrite sparse mappers in terms of a functor template function
David Bateman <dbateman@free.fr>
parents:
7470
diff
changeset
|
563 } |
5164 | 564 }; |
565 | |
566 // NOTE: these functions should be friends of the Sparse<T> class and | |
567 // Sparse<T>::dimensions should be protected, not public, but we can't | |
568 // do that because of bugs in gcc prior to 3.3. | |
569 | |
570 template <class LT, class RT> | |
571 /* friend */ int | |
572 assign (Sparse<LT>& lhs, const Sparse<RT>& rhs); | |
573 | |
574 template <class LT, class RT> | |
575 /* friend */ int | |
576 assign1 (Sparse<LT>& lhs, const Sparse<RT>& rhs); | |
577 | |
6708 | 578 #define INSTANTIATE_SPARSE_ASSIGN(LT, RT, API) \ |
579 template API int assign (Sparse<LT>&, const Sparse<RT>&); \ | |
580 template API int assign1 (Sparse<LT>&, const Sparse<RT>&); | |
5164 | 581 |
6708 | 582 #define INSTANTIATE_SPARSE(T, API) \ |
583 template class API Sparse<T>; | |
5164 | 584 |
6708 | 585 #define INSTANTIATE_SPARSE_AND_ASSIGN(T, API) \ |
586 INSTANTIATE_SPARSE (T, API); \ | |
587 INSTANTIATE_SPARSE_ASSIGN (T, T, API) | |
5164 | 588 |
589 #endif | |
590 | |
591 /* | |
592 ;;; Local Variables: *** | |
593 ;;; mode: C++ *** | |
594 ;;; End: *** | |
595 */ |