Mercurial > hg > segmenter-vamp-plugin
comparison armadillo-3.900.4/include/armadillo_bits/SpSubview_iterators_meat.hpp @ 49:1ec0e2823891
Switch to using subrepo copies of qm-dsp, nnls-chroma, vamp-plugin-sdk; update Armadillo version; assume build without external BLAS/LAPACK
author | Chris Cannam |
---|---|
date | Thu, 13 Jun 2013 10:25:24 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
48:69251e11a913 | 49:1ec0e2823891 |
---|---|
1 // Copyright (C) 2012 Ryan Curtin | |
2 // Copyright (C) 2012 Conrad Sanderson | |
3 // | |
4 // This Source Code Form is subject to the terms of the Mozilla Public | |
5 // License, v. 2.0. If a copy of the MPL was not distributed with this | |
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
7 | |
8 //! \addtogroup SpSubview | |
9 //! @{ | |
10 | |
11 /////////////////////////////////////////////////////////////////////////////// | |
12 // SpSubview::iterator_base implementation // | |
13 /////////////////////////////////////////////////////////////////////////////// | |
14 | |
15 template<typename eT> | |
16 inline | |
17 SpSubview<eT>::iterator_base::iterator_base(const SpSubview<eT>& in_M) | |
18 : M(in_M) | |
19 , internal_col(0) | |
20 , internal_pos(0) | |
21 , skip_pos(0) | |
22 { | |
23 // Technically this iterator is invalid (it may not point to a real element). | |
24 } | |
25 | |
26 | |
27 | |
28 template<typename eT> | |
29 inline | |
30 SpSubview<eT>::iterator_base::iterator_base(const SpSubview<eT>& in_M, const uword in_col, const uword in_pos, const uword in_skip_pos) | |
31 : M(in_M) | |
32 , internal_col(in_col) | |
33 , internal_pos(in_pos) | |
34 , skip_pos (in_skip_pos) | |
35 { | |
36 // Nothing to do. | |
37 } | |
38 | |
39 | |
40 | |
41 template<typename eT> | |
42 inline | |
43 eT | |
44 SpSubview<eT>::iterator_base::operator*() const | |
45 { | |
46 return M.m.values[internal_pos + skip_pos]; | |
47 } | |
48 | |
49 | |
50 | |
51 /////////////////////////////////////////////////////////////////////////////// | |
52 // SpSubview::const_iterator implementation // | |
53 /////////////////////////////////////////////////////////////////////////////// | |
54 | |
55 template<typename eT> | |
56 inline | |
57 SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, const uword initial_pos) | |
58 : iterator_base(in_M, 0, initial_pos, 0) | |
59 { | |
60 // Corner case for empty subviews. | |
61 if(in_M.n_nonzero == 0) | |
62 { | |
63 iterator_base::internal_col = in_M.n_cols; | |
64 iterator_base::skip_pos = in_M.m.n_nonzero; | |
65 return; | |
66 } | |
67 | |
68 // Figure out the row and column of the position. | |
69 // lskip_pos holds the number of values which aren't part of this subview. | |
70 const uword aux_col = iterator_base::M.aux_col1; | |
71 const uword aux_row = iterator_base::M.aux_row1; | |
72 const uword ln_rows = iterator_base::M.n_rows; | |
73 const uword ln_cols = iterator_base::M.n_cols; | |
74 | |
75 uword cur_pos = 0; // off by one because we might be searching for pos 0 | |
76 uword lskip_pos = iterator_base::M.m.col_ptrs[aux_col]; | |
77 uword cur_col = 0; | |
78 | |
79 while(cur_pos < (iterator_base::internal_pos + 1)) | |
80 { | |
81 // Have we stepped forward a column (or multiple columns)? | |
82 while(((lskip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols)) | |
83 { | |
84 ++cur_col; | |
85 } | |
86 | |
87 // See if the current position is in the subview. | |
88 const uword row_index = iterator_base::M.m.row_indices[cur_pos + lskip_pos]; | |
89 if(row_index < aux_row) | |
90 { | |
91 ++lskip_pos; // not valid | |
92 } | |
93 else if(row_index < (aux_row + ln_rows)) | |
94 { | |
95 ++cur_pos; // valid, in the subview | |
96 } | |
97 else | |
98 { | |
99 // skip to end of column | |
100 const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; | |
101 lskip_pos += (next_colptr - (cur_pos + lskip_pos)); | |
102 } | |
103 } | |
104 | |
105 iterator_base::internal_col = cur_col; | |
106 iterator_base::skip_pos = lskip_pos; | |
107 } | |
108 | |
109 | |
110 | |
111 template<typename eT> | |
112 inline | |
113 SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, const uword in_row, const uword in_col) | |
114 : iterator_base(in_M, in_col, 0, 0) | |
115 { | |
116 // Corner case for empty subviews. | |
117 if(in_M.n_nonzero == 0) | |
118 { | |
119 // We must be at the last position. | |
120 iterator_base::internal_col = in_M.n_cols; | |
121 iterator_base::skip_pos = in_M.m.n_nonzero; | |
122 return; | |
123 } | |
124 | |
125 // We have a destination we want to be just after, but don't know what position that is. | |
126 // Because we have to count the points in this subview and not in this subview, this becomes a little difficult and slow. | |
127 const uword aux_col = iterator_base::M.aux_col1; | |
128 const uword aux_row = iterator_base::M.aux_row1; | |
129 const uword ln_rows = iterator_base::M.n_rows; | |
130 const uword ln_cols = iterator_base::M.n_cols; | |
131 | |
132 uword cur_pos = 0; | |
133 uword skip_pos = iterator_base::M.m.col_ptrs[aux_col]; | |
134 uword cur_col = 0; | |
135 | |
136 while(cur_col < in_col) | |
137 { | |
138 // See if the current position is in the subview. | |
139 const uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
140 if(row_index < aux_row) | |
141 { | |
142 ++skip_pos; | |
143 } | |
144 else if(row_index < (aux_row + ln_rows)) | |
145 { | |
146 ++cur_pos; | |
147 } | |
148 else | |
149 { | |
150 // skip to end of column | |
151 const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; | |
152 skip_pos += (next_colptr - (cur_pos + skip_pos)); | |
153 } | |
154 | |
155 // Have we stepped forward a column (or multiple columns)? | |
156 while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols)) | |
157 { | |
158 ++cur_col; | |
159 } | |
160 } | |
161 | |
162 // Now we are either on the right column or ahead of it. | |
163 if(cur_col == in_col) | |
164 { | |
165 // We have to find the right row index. | |
166 uword row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
167 while((row_index < (in_row + aux_row))) | |
168 { | |
169 if(row_index < aux_row) | |
170 { | |
171 ++skip_pos; | |
172 } | |
173 else | |
174 { | |
175 ++cur_pos; | |
176 } | |
177 | |
178 // Ensure we didn't step forward a column; if we did, we need to stop. | |
179 while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols)) | |
180 { | |
181 ++cur_col; | |
182 } | |
183 | |
184 if(cur_col != in_col) | |
185 { | |
186 break; | |
187 } | |
188 | |
189 row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
190 } | |
191 } | |
192 | |
193 // Now we need to find the next valid position in the subview. | |
194 uword row_index; | |
195 while(true) | |
196 { | |
197 const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; | |
198 row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
199 | |
200 // Are we at the last position? | |
201 if(cur_col >= ln_cols) | |
202 { | |
203 cur_col = ln_cols; | |
204 // Make sure we will be pointing at the last element in the parent matrix. | |
205 skip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero; | |
206 break; | |
207 } | |
208 | |
209 if(row_index < aux_row) | |
210 { | |
211 ++skip_pos; | |
212 } | |
213 else if(row_index < (aux_row + ln_rows)) | |
214 { | |
215 break; // found | |
216 } | |
217 else | |
218 { | |
219 skip_pos += (next_colptr - (cur_pos + skip_pos)); | |
220 } | |
221 | |
222 // Did we move any columns? | |
223 while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols)) | |
224 { | |
225 ++cur_col; | |
226 } | |
227 } | |
228 | |
229 // It is possible we have moved another column. | |
230 while(((skip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]) && (cur_col < ln_cols)) | |
231 { | |
232 ++cur_col; | |
233 } | |
234 | |
235 iterator_base::internal_pos = cur_pos; | |
236 iterator_base::skip_pos = skip_pos; | |
237 iterator_base::internal_col = cur_col; | |
238 } | |
239 | |
240 | |
241 | |
242 template<typename eT> | |
243 inline | |
244 SpSubview<eT>::const_iterator::const_iterator(const SpSubview<eT>& in_M, uword in_row, uword in_col, uword in_pos, uword in_skip_pos) | |
245 : iterator_base(in_M, in_col, in_pos, in_skip_pos) | |
246 { | |
247 // Nothing to do. | |
248 } | |
249 | |
250 | |
251 | |
252 template<typename eT> | |
253 inline | |
254 SpSubview<eT>::const_iterator::const_iterator(const const_iterator& other) | |
255 : iterator_base(other.M, other.internal_col, other.internal_pos, other.skip_pos) | |
256 { | |
257 // Nothing to do. | |
258 } | |
259 | |
260 | |
261 | |
262 template<typename eT> | |
263 inline | |
264 typename SpSubview<eT>::const_iterator& | |
265 SpSubview<eT>::const_iterator::operator++() | |
266 { | |
267 const uword aux_col = iterator_base::M.aux_col1; | |
268 const uword aux_row = iterator_base::M.aux_row1; | |
269 const uword ln_rows = iterator_base::M.n_rows; | |
270 const uword ln_cols = iterator_base::M.n_cols; | |
271 | |
272 uword cur_col = iterator_base::internal_col; | |
273 uword cur_pos = iterator_base::internal_pos + 1; | |
274 uword lskip_pos = iterator_base::skip_pos; | |
275 uword row_index; | |
276 | |
277 while(true) | |
278 { | |
279 const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; | |
280 row_index = iterator_base::M.m.row_indices[cur_pos + lskip_pos]; | |
281 | |
282 // Did we move any columns? | |
283 while((cur_col < ln_cols) && ((lskip_pos + cur_pos) >= iterator_base::M.m.col_ptrs[cur_col + aux_col + 1])) | |
284 { | |
285 ++cur_col; | |
286 } | |
287 | |
288 // Are we at the last position? | |
289 if(cur_col >= ln_cols) | |
290 { | |
291 cur_col = ln_cols; | |
292 // Make sure we will be pointing at the last element in the parent matrix. | |
293 lskip_pos = iterator_base::M.m.n_nonzero - iterator_base::M.n_nonzero; | |
294 break; | |
295 } | |
296 | |
297 if(row_index < aux_row) | |
298 { | |
299 ++lskip_pos; | |
300 } | |
301 else if(row_index < (aux_row + ln_rows)) | |
302 { | |
303 break; // found | |
304 } | |
305 else | |
306 { | |
307 lskip_pos += (next_colptr - (cur_pos + lskip_pos)); | |
308 } | |
309 } | |
310 | |
311 iterator_base::internal_pos = cur_pos; | |
312 iterator_base::internal_col = cur_col; | |
313 iterator_base::skip_pos = lskip_pos; | |
314 | |
315 return *this; | |
316 } | |
317 | |
318 | |
319 | |
320 template<typename eT> | |
321 inline | |
322 typename SpSubview<eT>::const_iterator | |
323 SpSubview<eT>::const_iterator::operator++(int) | |
324 { | |
325 typename SpSubview<eT>::const_iterator tmp(*this); | |
326 | |
327 ++(*this); | |
328 | |
329 return tmp; | |
330 } | |
331 | |
332 | |
333 | |
334 template<typename eT> | |
335 inline | |
336 typename SpSubview<eT>::const_iterator& | |
337 SpSubview<eT>::const_iterator::operator--() | |
338 { | |
339 const uword aux_col = iterator_base::M.aux_col1; | |
340 const uword aux_row = iterator_base::M.aux_row1; | |
341 const uword ln_rows = iterator_base::M.n_rows; | |
342 | |
343 uword cur_col = iterator_base::internal_col; | |
344 uword cur_pos = iterator_base::internal_pos - 1; | |
345 uword skip_pos = iterator_base::skip_pos; | |
346 | |
347 // Special condition for end of iterator. | |
348 if((skip_pos + cur_pos + 1) == iterator_base::M.m.n_nonzero) | |
349 { | |
350 // We are at the last element. So we need to set skip_pos back to what it | |
351 // would be if we didn't manually modify it back in operator++(). | |
352 skip_pos = iterator_base::M.m.col_ptrs[cur_col + aux_col] - iterator_base::internal_pos; | |
353 } | |
354 | |
355 uword row_index; | |
356 | |
357 while(true) | |
358 { | |
359 const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | |
360 row_index = iterator_base::M.m.row_indices[cur_pos + skip_pos]; | |
361 | |
362 // Did we move back any columns? | |
363 while((skip_pos + cur_pos) < iterator_base::M.m.col_ptrs[cur_col + aux_col]) | |
364 { | |
365 --cur_col; | |
366 } | |
367 | |
368 if(row_index < aux_row) | |
369 { | |
370 skip_pos -= (colptr - (cur_pos + skip_pos) + 1); | |
371 } | |
372 else if(row_index < (aux_row + ln_rows)) | |
373 { | |
374 break; // found | |
375 } | |
376 else | |
377 { | |
378 --skip_pos; | |
379 } | |
380 } | |
381 | |
382 iterator_base::internal_pos = cur_pos; | |
383 iterator_base::skip_pos = skip_pos; | |
384 iterator_base::internal_col = cur_col; | |
385 | |
386 return *this; | |
387 } | |
388 | |
389 | |
390 | |
391 template<typename eT> | |
392 inline | |
393 typename SpSubview<eT>::const_iterator | |
394 SpSubview<eT>::const_iterator::operator--(int) | |
395 { | |
396 typename SpSubview<eT>::const_iterator tmp(*this); | |
397 | |
398 --(*this); | |
399 | |
400 return tmp; | |
401 } | |
402 | |
403 | |
404 | |
405 template<typename eT> | |
406 inline | |
407 bool | |
408 SpSubview<eT>::const_iterator::operator==(const const_iterator& rhs) const | |
409 { | |
410 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); | |
411 } | |
412 | |
413 | |
414 | |
415 template<typename eT> | |
416 inline | |
417 bool | |
418 SpSubview<eT>::const_iterator::operator!=(const const_iterator& rhs) const | |
419 { | |
420 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); | |
421 } | |
422 | |
423 | |
424 | |
425 template<typename eT> | |
426 inline | |
427 bool | |
428 SpSubview<eT>::const_iterator::operator==(const typename SpMat<eT>::const_iterator& rhs) const | |
429 { | |
430 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); | |
431 } | |
432 | |
433 | |
434 | |
435 template<typename eT> | |
436 inline | |
437 bool | |
438 SpSubview<eT>::const_iterator::operator!=(const typename SpMat<eT>::const_iterator& rhs) const | |
439 { | |
440 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); | |
441 } | |
442 | |
443 | |
444 | |
445 template<typename eT> | |
446 inline | |
447 bool | |
448 SpSubview<eT>::const_iterator::operator==(const const_row_iterator& rhs) const | |
449 { | |
450 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); | |
451 } | |
452 | |
453 | |
454 | |
455 template<typename eT> | |
456 inline | |
457 bool | |
458 SpSubview<eT>::const_iterator::operator!=(const const_row_iterator& rhs) const | |
459 { | |
460 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); | |
461 } | |
462 | |
463 | |
464 | |
465 template<typename eT> | |
466 inline | |
467 bool | |
468 SpSubview<eT>::const_iterator::operator==(const typename SpMat<eT>::const_row_iterator& rhs) const | |
469 { | |
470 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col); | |
471 } | |
472 | |
473 | |
474 | |
475 template<typename eT> | |
476 inline | |
477 bool | |
478 SpSubview<eT>::const_iterator::operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const | |
479 { | |
480 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col); | |
481 } | |
482 | |
483 | |
484 | |
485 /////////////////////////////////////////////////////////////////////////////// | |
486 // SpSubview<eT>::iterator implementation // | |
487 /////////////////////////////////////////////////////////////////////////////// | |
488 | |
489 template<typename eT> | |
490 inline | |
491 SpValProxy<SpSubview<eT> > | |
492 SpSubview<eT>::iterator::operator*() | |
493 { | |
494 return SpValProxy<SpSubview<eT> >( | |
495 iterator_base::row(), | |
496 iterator_base::col(), | |
497 access::rw(iterator_base::M), | |
498 &(access::rw(iterator_base::M.m.values[iterator_base::internal_pos + iterator_base::skip_pos]))); | |
499 } | |
500 | |
501 | |
502 | |
503 template<typename eT> | |
504 inline | |
505 typename SpSubview<eT>::iterator& | |
506 SpSubview<eT>::iterator::operator++() | |
507 { | |
508 const_iterator::operator++(); | |
509 return *this; | |
510 } | |
511 | |
512 | |
513 | |
514 template<typename eT> | |
515 inline | |
516 typename SpSubview<eT>::iterator | |
517 SpSubview<eT>::iterator::operator++(int) | |
518 { | |
519 typename SpSubview<eT>::iterator tmp(*this); | |
520 | |
521 const_iterator::operator++(); | |
522 | |
523 return tmp; | |
524 } | |
525 | |
526 | |
527 | |
528 template<typename eT> | |
529 inline | |
530 typename SpSubview<eT>::iterator& | |
531 SpSubview<eT>::iterator::operator--() | |
532 { | |
533 const_iterator::operator--(); | |
534 return *this; | |
535 } | |
536 | |
537 | |
538 | |
539 template<typename eT> | |
540 inline | |
541 typename SpSubview<eT>::iterator | |
542 SpSubview<eT>::iterator::operator--(int) | |
543 { | |
544 typename SpSubview<eT>::iterator tmp(*this); | |
545 | |
546 const_iterator::operator--(); | |
547 | |
548 return tmp; | |
549 } | |
550 | |
551 | |
552 | |
553 /////////////////////////////////////////////////////////////////////////////// | |
554 // SpSubview<eT>::const_row_iterator implementation // | |
555 /////////////////////////////////////////////////////////////////////////////// | |
556 | |
557 template<typename eT> | |
558 inline | |
559 SpSubview<eT>::const_row_iterator::const_row_iterator(const SpSubview<eT>& in_M, uword initial_pos) | |
560 : iterator_base(in_M, 0, initial_pos, 0) | |
561 , internal_row(0) | |
562 , actual_pos(0) | |
563 { | |
564 // Corner case for empty subviews. | |
565 if(in_M.n_nonzero == 0) | |
566 { | |
567 iterator_base::internal_col = 0; | |
568 internal_row = in_M.n_rows; | |
569 iterator_base::skip_pos = in_M.m.n_nonzero; | |
570 return; | |
571 } | |
572 | |
573 const uword aux_col = iterator_base::M.aux_col1; | |
574 const uword aux_row = iterator_base::M.aux_row1; | |
575 const uword ln_cols = iterator_base::M.n_cols; | |
576 | |
577 // We don't know where the elements are in each row. What we will do is | |
578 // loop across all valid columns looking for elements in row 0 (and add to | |
579 // our sum), then in row 1, and so forth, until we get to the desired | |
580 // position. | |
581 uword cur_pos = -1; | |
582 uword cur_row = 0; | |
583 uword cur_col = 0; | |
584 | |
585 while(true) | |
586 { | |
587 // Is there anything in the column we are looking at? | |
588 const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | |
589 const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; | |
590 | |
591 for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_indices[ind] <= (cur_row + aux_row)); ++ind) | |
592 { | |
593 // There is something in this column. Is it in the row we are looking at? | |
594 const uword row_index = iterator_base::M.m.row_indices[ind]; | |
595 if(row_index == (cur_row + aux_row)) | |
596 { | |
597 // Yes, it is in the right row. | |
598 if(++cur_pos == iterator_base::internal_pos) | |
599 { | |
600 iterator_base::internal_col = cur_col; | |
601 internal_row = cur_row; | |
602 actual_pos = ind; | |
603 | |
604 return; | |
605 } | |
606 | |
607 // We are done with this column. Break to the column incrementing code (directly below). | |
608 break; | |
609 } | |
610 else if(row_index > (cur_row + aux_row)) | |
611 { | |
612 break; // Can't be in this column. | |
613 } | |
614 } | |
615 | |
616 cur_col++; // Done with the column. Move on. | |
617 if(cur_col == ln_cols) | |
618 { | |
619 // Out of columns. Loop back to the beginning and look on the next row. | |
620 cur_col = 0; | |
621 cur_row++; | |
622 } | |
623 } | |
624 } | |
625 | |
626 | |
627 | |
628 template<typename eT> | |
629 inline | |
630 SpSubview<eT>::const_row_iterator::const_row_iterator(const SpSubview<eT>& in_M, uword in_row, uword in_col) | |
631 : iterator_base(in_M, in_col, 0, 0) | |
632 , internal_row(0) | |
633 , actual_pos(0) | |
634 { | |
635 // We have a destination we want to be just after, but don't know what that | |
636 // position is. Because we will have to loop over everything anyway, create | |
637 // another iterator and loop it until it is at the right place, then take its | |
638 // information. | |
639 const_row_iterator it(in_M, 0); | |
640 while((it.row() < in_row) || ((it.row() == in_row) && (it.col() < in_col))) | |
641 { | |
642 ++it; | |
643 } | |
644 | |
645 iterator_base::internal_col = it.col(); | |
646 iterator_base::internal_pos = it.pos(); | |
647 iterator_base::skip_pos = it.skip_pos; | |
648 internal_row = it.internal_row; | |
649 actual_pos = it.actual_pos; | |
650 } | |
651 | |
652 | |
653 | |
654 template<typename eT> | |
655 inline | |
656 SpSubview<eT>::const_row_iterator::const_row_iterator(const const_row_iterator& other) | |
657 : iterator_base(other.M, other.internal_col, other.internal_pos, other.skip_pos) | |
658 , internal_row(other.internal_row) | |
659 , actual_pos(other.actual_pos) | |
660 { | |
661 // Nothing to do. | |
662 } | |
663 | |
664 | |
665 | |
666 template<typename eT> | |
667 inline | |
668 typename SpSubview<eT>::const_row_iterator& | |
669 SpSubview<eT>::const_row_iterator::operator++() | |
670 { | |
671 // We just need to find the next nonzero element. | |
672 ++iterator_base::internal_pos; | |
673 | |
674 // If we have exceeded the bounds, update accordingly. | |
675 if(iterator_base::internal_pos >= iterator_base::M.n_nonzero) | |
676 { | |
677 internal_row = iterator_base::M.n_rows; | |
678 iterator_base::internal_col = 0; | |
679 actual_pos = iterator_base::M.m.n_nonzero; | |
680 | |
681 return *this; | |
682 } | |
683 | |
684 // Otherwise, we need to search. | |
685 uword cur_col = iterator_base::internal_col; | |
686 uword cur_row = internal_row; | |
687 | |
688 const uword aux_col = iterator_base::M.aux_col1; | |
689 const uword aux_row = iterator_base::M.aux_row1; | |
690 const uword ln_cols = iterator_base::M.n_cols; | |
691 | |
692 while(true) | |
693 { | |
694 // Increment the current column and see if we are on a new row. | |
695 if(++cur_col == ln_cols) | |
696 { | |
697 cur_col = 0; | |
698 ++cur_row; | |
699 } | |
700 | |
701 // Is there anything in this new column? | |
702 const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | |
703 const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; | |
704 | |
705 for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_indices[ind] <= (cur_row + aux_row)); ++ind) | |
706 { | |
707 const uword row_index = iterator_base::M.m.row_indices[ind]; | |
708 | |
709 if((row_index - aux_row) == cur_row) | |
710 { | |
711 // We have successfully incremented. | |
712 internal_row = cur_row; | |
713 actual_pos = ind; | |
714 iterator_base::internal_col = cur_col; | |
715 | |
716 return *this; | |
717 } | |
718 } | |
719 } | |
720 } | |
721 | |
722 | |
723 | |
724 template<typename eT> | |
725 inline | |
726 typename SpSubview<eT>::const_row_iterator | |
727 SpSubview<eT>::const_row_iterator::operator++(int) | |
728 { | |
729 typename SpSubview<eT>::const_row_iterator tmp(*this); | |
730 | |
731 ++(*this); | |
732 | |
733 return tmp; | |
734 } | |
735 | |
736 | |
737 | |
738 template<typename eT> | |
739 inline | |
740 typename SpSubview<eT>::const_row_iterator& | |
741 SpSubview<eT>::const_row_iterator::operator--() | |
742 { | |
743 // We just need to find the previous element. | |
744 // if(iterator_base::pos == 0) | |
745 // { | |
746 // // We cannot decrement. | |
747 // return *this; | |
748 // } | |
749 // else if(iterator_base::pos == iterator_base::M.n_nonzero) | |
750 // { | |
751 // // We will be coming off the last element. We need to reset the row correctly, because we set row = 0 in the last matrix position. | |
752 // iterator_base::row = iterator_base::M.n_rows - 1; | |
753 // } | |
754 // else if(iterator_base::pos > iterator_base::M.n_nonzero) | |
755 // { | |
756 // // This shouldn't happen... | |
757 // iterator_base::pos--; | |
758 // return *this; | |
759 // } | |
760 | |
761 iterator_base::internal_pos--; | |
762 | |
763 // We have to search backwards. | |
764 uword cur_col = iterator_base::internal_col; | |
765 uword cur_row = internal_row; | |
766 | |
767 const uword aux_col = iterator_base::M.aux_col1; | |
768 const uword aux_row = iterator_base::M.aux_row1; | |
769 const uword ln_cols = iterator_base::M.n_cols; | |
770 | |
771 while(true) | |
772 { | |
773 // Decrement the current column and see if we are on a new row. | |
774 if(--cur_col > ln_cols) | |
775 { | |
776 cur_col = ln_cols - 1; | |
777 cur_row--; | |
778 } | |
779 | |
780 // Is there anything in this new column? | |
781 const uword colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col]; | |
782 const uword next_colptr = iterator_base::M.m.col_ptrs[cur_col + aux_col + 1]; | |
783 | |
784 for(uword ind = colptr; (ind < next_colptr) && (iterator_base::M.m.row_indices[ind] <= (cur_row + aux_row)); ++ind) | |
785 { | |
786 const uword row_index = iterator_base::M.m.row_indices[ind]; | |
787 | |
788 if((row_index - aux_row) == cur_row) | |
789 { | |
790 iterator_base::internal_col = cur_col; | |
791 internal_row = cur_row; | |
792 actual_pos = ind; | |
793 | |
794 return *this; | |
795 } | |
796 } | |
797 } | |
798 } | |
799 | |
800 | |
801 | |
802 template<typename eT> | |
803 inline | |
804 typename SpSubview<eT>::const_row_iterator | |
805 SpSubview<eT>::const_row_iterator::operator--(int) | |
806 { | |
807 typename SpSubview<eT>::const_row_iterator tmp(*this); | |
808 | |
809 --(*this); | |
810 | |
811 return tmp; | |
812 } | |
813 | |
814 | |
815 | |
816 template<typename eT> | |
817 inline | |
818 bool | |
819 SpSubview<eT>::const_row_iterator::operator==(const const_iterator& rhs) const | |
820 { | |
821 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); | |
822 } | |
823 | |
824 | |
825 | |
826 template<typename eT> | |
827 inline | |
828 bool | |
829 SpSubview<eT>::const_row_iterator::operator!=(const const_iterator& rhs) const | |
830 { | |
831 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); | |
832 } | |
833 | |
834 | |
835 | |
836 template<typename eT> | |
837 inline | |
838 bool | |
839 SpSubview<eT>::const_row_iterator::operator==(const typename SpMat<eT>::const_iterator& rhs) const | |
840 { | |
841 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); | |
842 } | |
843 | |
844 | |
845 | |
846 template<typename eT> | |
847 inline | |
848 bool | |
849 SpSubview<eT>::const_row_iterator::operator!=(const typename SpMat<eT>::const_iterator& rhs) const | |
850 { | |
851 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); | |
852 } | |
853 | |
854 | |
855 | |
856 template<typename eT> | |
857 inline | |
858 bool | |
859 SpSubview<eT>::const_row_iterator::operator==(const const_row_iterator& rhs) const | |
860 { | |
861 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); | |
862 } | |
863 | |
864 | |
865 | |
866 template<typename eT> | |
867 inline | |
868 bool | |
869 SpSubview<eT>::const_row_iterator::operator!=(const const_row_iterator& rhs) const | |
870 { | |
871 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); | |
872 } | |
873 | |
874 | |
875 | |
876 template<typename eT> | |
877 inline | |
878 bool | |
879 SpSubview<eT>::const_row_iterator::operator==(const typename SpMat<eT>::const_row_iterator& rhs) const | |
880 { | |
881 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col); | |
882 } | |
883 | |
884 | |
885 | |
886 template<typename eT> | |
887 inline | |
888 bool | |
889 SpSubview<eT>::const_row_iterator::operator!=(const typename SpMat<eT>::const_row_iterator& rhs) const | |
890 { | |
891 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col); | |
892 } | |
893 | |
894 | |
895 | |
896 /////////////////////////////////////////////////////////////////////////////// | |
897 // SpSubview<eT>::row_iterator implementation // | |
898 /////////////////////////////////////////////////////////////////////////////// | |
899 | |
900 template<typename eT> | |
901 inline | |
902 SpValProxy<SpSubview<eT> > | |
903 SpSubview<eT>::row_iterator::operator*() | |
904 { | |
905 return SpValProxy<SpSubview<eT> >( | |
906 const_row_iterator::internal_row, | |
907 iterator_base::internal_col, | |
908 access::rw(iterator_base::M), | |
909 &access::rw(iterator_base::M.m.values[const_row_iterator::actual_pos])); | |
910 } | |
911 | |
912 | |
913 | |
914 template<typename eT> | |
915 inline | |
916 typename SpSubview<eT>::row_iterator& | |
917 SpSubview<eT>::row_iterator::operator++() | |
918 { | |
919 const_row_iterator::operator++(); | |
920 return *this; | |
921 } | |
922 | |
923 | |
924 | |
925 template<typename eT> | |
926 inline | |
927 typename SpSubview<eT>::row_iterator | |
928 SpSubview<eT>::row_iterator::operator++(int) | |
929 { | |
930 typename SpSubview<eT>::row_iterator tmp(*this); | |
931 | |
932 ++(*this); | |
933 | |
934 return tmp; | |
935 } | |
936 | |
937 | |
938 | |
939 template<typename eT> | |
940 inline | |
941 typename SpSubview<eT>::row_iterator& | |
942 SpSubview<eT>::row_iterator::operator--() | |
943 { | |
944 const_row_iterator::operator--(); | |
945 return *this; | |
946 } | |
947 | |
948 | |
949 | |
950 template<typename eT> | |
951 inline | |
952 typename SpSubview<eT>::row_iterator | |
953 SpSubview<eT>::row_iterator::operator--(int) | |
954 { | |
955 typename SpSubview<eT>::row_iterator tmp(*this); | |
956 | |
957 --(*this); | |
958 | |
959 return tmp; | |
960 } | |
961 | |
962 //! @} |