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 //! @}