annotate armadillo-3.900.4/include/armadillo_bits/SpMat_iterators_meat.hpp @ 84:55a047986812 tip

Update library URI so as not to be document-local
author Chris Cannam
date Wed, 22 Apr 2020 14:21:57 +0100
parents 1ec0e2823891
children
rev   line source
Chris@49 1 // Copyright (C) 2011-2012 Ryan Curtin
Chris@49 2 // Copyright (C) 2011 Matthew Amidon
Chris@49 3 // Copyright (C) 2012 Conrad Sanderson
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 ///////////////////////////////////////////////////////////////////////////////
Chris@49 13 // SpMat::iterator_base implementation //
Chris@49 14 ///////////////////////////////////////////////////////////////////////////////
Chris@49 15
Chris@49 16 template<typename eT>
Chris@49 17 inline
Chris@49 18 SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M)
Chris@49 19 : M(in_M)
Chris@49 20 , internal_col(0)
Chris@49 21 , internal_pos(0)
Chris@49 22 {
Chris@49 23 // Technically this iterator is invalid (it may not point to a real element)
Chris@49 24 }
Chris@49 25
Chris@49 26
Chris@49 27
Chris@49 28 template<typename eT>
Chris@49 29 inline
Chris@49 30 SpMat<eT>::iterator_base::iterator_base(const SpMat<eT>& in_M, const uword in_col, const uword in_pos)
Chris@49 31 : M(in_M)
Chris@49 32 , internal_col(in_col)
Chris@49 33 , internal_pos(in_pos)
Chris@49 34 {
Chris@49 35 // Nothing to do.
Chris@49 36 }
Chris@49 37
Chris@49 38
Chris@49 39
Chris@49 40 template<typename eT>
Chris@49 41 inline
Chris@49 42 arma_hot
Chris@49 43 eT
Chris@49 44 SpMat<eT>::iterator_base::operator*() const
Chris@49 45 {
Chris@49 46 return M.values[internal_pos];
Chris@49 47 }
Chris@49 48
Chris@49 49
Chris@49 50
Chris@49 51 ///////////////////////////////////////////////////////////////////////////////
Chris@49 52 // SpMat::const_iterator implementation //
Chris@49 53 ///////////////////////////////////////////////////////////////////////////////
Chris@49 54
Chris@49 55 template<typename eT>
Chris@49 56 inline
Chris@49 57 SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword initial_pos)
Chris@49 58 : iterator_base(in_M, 0, initial_pos)
Chris@49 59 {
Chris@49 60 // Corner case for empty matrices.
Chris@49 61 if(in_M.n_nonzero == 0)
Chris@49 62 {
Chris@49 63 iterator_base::internal_col = in_M.n_cols;
Chris@49 64 return;
Chris@49 65 }
Chris@49 66
Chris@49 67 // Determine which column we should be in.
Chris@49 68 while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos)
Chris@49 69 {
Chris@49 70 iterator_base::internal_col++;
Chris@49 71 }
Chris@49 72 }
Chris@49 73
Chris@49 74
Chris@49 75
Chris@49 76 template<typename eT>
Chris@49 77 inline
Chris@49 78 SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, uword in_row, uword in_col)
Chris@49 79 : iterator_base(in_M, in_col, 0)
Chris@49 80 {
Chris@49 81 // So we have a position we want to be right after. Skip to the column.
Chris@49 82 iterator_base::internal_pos = iterator_base::M.col_ptrs[iterator_base::internal_col];
Chris@49 83
Chris@49 84 // Now we have to make sure that is the right column.
Chris@49 85 while(iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos)
Chris@49 86 {
Chris@49 87 iterator_base::internal_col++;
Chris@49 88 }
Chris@49 89
Chris@49 90 // Now we have to get to the right row.
Chris@49 91 while((iterator_base::M.row_indices[iterator_base::internal_pos] < in_row) && (iterator_base::internal_col == in_col))
Chris@49 92 {
Chris@49 93 ++(*this); // Increment iterator.
Chris@49 94 }
Chris@49 95 }
Chris@49 96
Chris@49 97
Chris@49 98
Chris@49 99 template<typename eT>
Chris@49 100 inline
Chris@49 101 SpMat<eT>::const_iterator::const_iterator(const SpMat<eT>& in_M, const uword /* in_row */, const uword in_col, const uword in_pos)
Chris@49 102 : iterator_base(in_M, in_col, in_pos)
Chris@49 103 {
Chris@49 104 // Nothing to do.
Chris@49 105 }
Chris@49 106
Chris@49 107
Chris@49 108
Chris@49 109 template<typename eT>
Chris@49 110 inline
Chris@49 111 SpMat<eT>::const_iterator::const_iterator(const typename SpMat<eT>::const_iterator& other)
Chris@49 112 : iterator_base(other.M, other.internal_col, other.internal_pos)
Chris@49 113 {
Chris@49 114 // Nothing to do.
Chris@49 115 }
Chris@49 116
Chris@49 117
Chris@49 118
Chris@49 119 template<typename eT>
Chris@49 120 inline
Chris@49 121 arma_hot
Chris@49 122 typename SpMat<eT>::const_iterator&
Chris@49 123 SpMat<eT>::const_iterator::operator++()
Chris@49 124 {
Chris@49 125 ++iterator_base::internal_pos;
Chris@49 126
Chris@49 127 if (iterator_base::internal_pos == iterator_base::M.n_nonzero)
Chris@49 128 {
Chris@49 129 iterator_base::internal_col = iterator_base::M.n_cols;
Chris@49 130 return *this;
Chris@49 131 }
Chris@49 132
Chris@49 133 // Check to see if we moved a column.
Chris@49 134 while (iterator_base::M.col_ptrs[iterator_base::internal_col + 1] <= iterator_base::internal_pos)
Chris@49 135 {
Chris@49 136 ++iterator_base::internal_col;
Chris@49 137 }
Chris@49 138
Chris@49 139 return *this;
Chris@49 140 }
Chris@49 141
Chris@49 142
Chris@49 143
Chris@49 144 template<typename eT>
Chris@49 145 inline
Chris@49 146 arma_hot
Chris@49 147 typename SpMat<eT>::const_iterator
Chris@49 148 SpMat<eT>::const_iterator::operator++(int)
Chris@49 149 {
Chris@49 150 typename SpMat<eT>::const_iterator tmp(*this);
Chris@49 151
Chris@49 152 ++(*this);
Chris@49 153
Chris@49 154 return tmp;
Chris@49 155 }
Chris@49 156
Chris@49 157
Chris@49 158
Chris@49 159 template<typename eT>
Chris@49 160 inline
Chris@49 161 arma_hot
Chris@49 162 typename SpMat<eT>::const_iterator&
Chris@49 163 SpMat<eT>::const_iterator::operator--()
Chris@49 164 {
Chris@49 165 //iterator_base::M.print("M");
Chris@49 166
Chris@49 167 // printf("decrement from %d, %d, %d\n", iterator_base::internal_pos, iterator_base::internal_col, iterator_base::row());
Chris@49 168
Chris@49 169 --iterator_base::internal_pos;
Chris@49 170
Chris@49 171 // printf("now pos %d\n", iterator_base::internal_pos);
Chris@49 172
Chris@49 173 // First, see if we moved back a column.
Chris@49 174 while (iterator_base::internal_pos < iterator_base::M.col_ptrs[iterator_base::internal_col])
Chris@49 175 {
Chris@49 176 // printf("colptr %d (col %d)\n", iterator_base::M.col_ptrs[iterator_base::internal_col], iterator_base::internal_col);
Chris@49 177
Chris@49 178 --iterator_base::internal_col;
Chris@49 179 }
Chris@49 180
Chris@49 181
Chris@49 182 return *this;
Chris@49 183 }
Chris@49 184
Chris@49 185
Chris@49 186
Chris@49 187 template<typename eT>
Chris@49 188 inline
Chris@49 189 arma_hot
Chris@49 190 typename SpMat<eT>::const_iterator
Chris@49 191 SpMat<eT>::const_iterator::operator--(int)
Chris@49 192 {
Chris@49 193 typename SpMat<eT>::const_iterator tmp(*this);
Chris@49 194
Chris@49 195 --(*this);
Chris@49 196
Chris@49 197 return tmp;
Chris@49 198 }
Chris@49 199
Chris@49 200
Chris@49 201
Chris@49 202 template<typename eT>
Chris@49 203 inline
Chris@49 204 arma_hot
Chris@49 205 bool
Chris@49 206 SpMat<eT>::const_iterator::operator==(const const_iterator& rhs) const
Chris@49 207 {
Chris@49 208 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 209 }
Chris@49 210
Chris@49 211
Chris@49 212
Chris@49 213 template<typename eT>
Chris@49 214 inline
Chris@49 215 arma_hot
Chris@49 216 bool
Chris@49 217 SpMat<eT>::const_iterator::operator!=(const const_iterator& rhs) const
Chris@49 218 {
Chris@49 219 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 220 }
Chris@49 221
Chris@49 222
Chris@49 223
Chris@49 224 template<typename eT>
Chris@49 225 inline
Chris@49 226 arma_hot
Chris@49 227 bool
Chris@49 228 SpMat<eT>::const_iterator::operator==(const typename SpSubview<eT>::const_iterator& rhs) const
Chris@49 229 {
Chris@49 230 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 231 }
Chris@49 232
Chris@49 233
Chris@49 234
Chris@49 235 template<typename eT>
Chris@49 236 inline
Chris@49 237 arma_hot
Chris@49 238 bool
Chris@49 239 SpMat<eT>::const_iterator::operator!=(const typename SpSubview<eT>::const_iterator& rhs) const
Chris@49 240 {
Chris@49 241 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 242 }
Chris@49 243
Chris@49 244
Chris@49 245
Chris@49 246 template<typename eT>
Chris@49 247 inline
Chris@49 248 arma_hot
Chris@49 249 bool
Chris@49 250 SpMat<eT>::const_iterator::operator==(const const_row_iterator& rhs) const
Chris@49 251 {
Chris@49 252 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 253 }
Chris@49 254
Chris@49 255
Chris@49 256
Chris@49 257 template<typename eT>
Chris@49 258 inline
Chris@49 259 arma_hot
Chris@49 260 bool
Chris@49 261 SpMat<eT>::const_iterator::operator!=(const const_row_iterator& rhs) const
Chris@49 262 {
Chris@49 263 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 264 }
Chris@49 265
Chris@49 266
Chris@49 267
Chris@49 268 template<typename eT>
Chris@49 269 inline
Chris@49 270 arma_hot
Chris@49 271 bool
Chris@49 272 SpMat<eT>::const_iterator::operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const
Chris@49 273 {
Chris@49 274 return (rhs.row() == (*this).row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 275 }
Chris@49 276
Chris@49 277
Chris@49 278
Chris@49 279 template<typename eT>
Chris@49 280 inline
Chris@49 281 arma_hot
Chris@49 282 bool
Chris@49 283 SpMat<eT>::const_iterator::operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const
Chris@49 284 {
Chris@49 285 return (rhs.row() != (*this).row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 286 }
Chris@49 287
Chris@49 288
Chris@49 289
Chris@49 290 ///////////////////////////////////////////////////////////////////////////////
Chris@49 291 // SpMat::iterator implementation //
Chris@49 292 ///////////////////////////////////////////////////////////////////////////////
Chris@49 293
Chris@49 294 template<typename eT>
Chris@49 295 inline
Chris@49 296 arma_hot
Chris@49 297 SpValProxy<SpMat<eT> >
Chris@49 298 SpMat<eT>::iterator::operator*()
Chris@49 299 {
Chris@49 300 return SpValProxy<SpMat<eT> >(
Chris@49 301 iterator_base::M.row_indices[iterator_base::internal_pos],
Chris@49 302 iterator_base::internal_col,
Chris@49 303 access::rw(iterator_base::M),
Chris@49 304 &access::rw(iterator_base::M.values[iterator_base::internal_pos]));
Chris@49 305 }
Chris@49 306
Chris@49 307
Chris@49 308
Chris@49 309 template<typename eT>
Chris@49 310 inline
Chris@49 311 arma_hot
Chris@49 312 typename SpMat<eT>::iterator&
Chris@49 313 SpMat<eT>::iterator::operator++()
Chris@49 314 {
Chris@49 315 const_iterator::operator++();
Chris@49 316 return *this;
Chris@49 317 }
Chris@49 318
Chris@49 319
Chris@49 320
Chris@49 321 template<typename eT>
Chris@49 322 inline
Chris@49 323 arma_hot
Chris@49 324 typename SpMat<eT>::iterator
Chris@49 325 SpMat<eT>::iterator::operator++(int)
Chris@49 326 {
Chris@49 327 typename SpMat<eT>::iterator tmp(*this);
Chris@49 328
Chris@49 329 const_iterator::operator++();
Chris@49 330
Chris@49 331 return tmp;
Chris@49 332 }
Chris@49 333
Chris@49 334
Chris@49 335
Chris@49 336 template<typename eT>
Chris@49 337 inline
Chris@49 338 arma_hot
Chris@49 339 typename SpMat<eT>::iterator&
Chris@49 340 SpMat<eT>::iterator::operator--()
Chris@49 341 {
Chris@49 342 const_iterator::operator--();
Chris@49 343 return *this;
Chris@49 344 }
Chris@49 345
Chris@49 346
Chris@49 347
Chris@49 348 template<typename eT>
Chris@49 349 inline
Chris@49 350 arma_hot
Chris@49 351 typename SpMat<eT>::iterator
Chris@49 352 SpMat<eT>::iterator::operator--(int)
Chris@49 353 {
Chris@49 354 typename SpMat<eT>::iterator tmp(*this);
Chris@49 355
Chris@49 356 const_iterator::operator--();
Chris@49 357
Chris@49 358 return tmp;
Chris@49 359 }
Chris@49 360
Chris@49 361
Chris@49 362
Chris@49 363 ///////////////////////////////////////////////////////////////////////////////
Chris@49 364 // SpMat::const_row_iterator implementation //
Chris@49 365 ///////////////////////////////////////////////////////////////////////////////
Chris@49 366
Chris@49 367 /**
Chris@49 368 * Initialize the const_row_iterator.
Chris@49 369 */
Chris@49 370 template<typename eT>
Chris@49 371 inline
Chris@49 372 SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uword initial_pos)
Chris@49 373 : iterator_base(in_M, 0, initial_pos)
Chris@49 374 , internal_row(0)
Chris@49 375 , actual_pos(0)
Chris@49 376 {
Chris@49 377 // Corner case for empty matrix.
Chris@49 378 if(in_M.n_nonzero == 0)
Chris@49 379 {
Chris@49 380 iterator_base::internal_col = 0;
Chris@49 381 internal_row = in_M.n_rows;
Chris@49 382 return;
Chris@49 383 }
Chris@49 384
Chris@49 385 // We don't count zeroes in our position count, so we have to find the nonzero
Chris@49 386 // value corresponding to the given initial position. We assume initial_pos
Chris@49 387 // is valid.
Chris@49 388
Chris@49 389 // This is irritating because we don't know where the elements are in each
Chris@49 390 // row. What we will do is loop across all columns looking for elements in
Chris@49 391 // row 0 (and add to our sum), then in row 1, and so forth, until we get to
Chris@49 392 // the desired position.
Chris@49 393 uword cur_pos = -1;
Chris@49 394 uword cur_row = 0;
Chris@49 395 uword cur_col = 0;
Chris@49 396
Chris@49 397 while(true) // This loop is terminated from the inside.
Chris@49 398 {
Chris@49 399 // Is there anything in the column we are looking at?
Chris@49 400 for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++)
Chris@49 401 {
Chris@49 402 // There is something in this column. Is it in the row we are looking at?
Chris@49 403 const uword row_index = iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind];
Chris@49 404 if (row_index == cur_row)
Chris@49 405 {
Chris@49 406 // Yes, it is what we are looking for. Increment our current position.
Chris@49 407 if (++cur_pos == iterator_base::internal_pos)
Chris@49 408 {
Chris@49 409 actual_pos = iterator_base::M.col_ptrs[cur_col] + ind;
Chris@49 410 internal_row = cur_row;
Chris@49 411 iterator_base::internal_col = cur_col;
Chris@49 412
Chris@49 413 return;
Chris@49 414 }
Chris@49 415
Chris@49 416 // We are done with this column. Break to the column incrementing code (directly below).
Chris@49 417 break;
Chris@49 418 }
Chris@49 419 else if(row_index > cur_row)
Chris@49 420 {
Chris@49 421 break; // Can't be in this column.
Chris@49 422 }
Chris@49 423 }
Chris@49 424
Chris@49 425 cur_col++; // Done with the column. Move on.
Chris@49 426 if (cur_col == iterator_base::M.n_cols)
Chris@49 427 {
Chris@49 428 // We are out of columns. Loop back to the beginning and look on the
Chris@49 429 // next row.
Chris@49 430 cur_col = 0;
Chris@49 431 cur_row++;
Chris@49 432 }
Chris@49 433 }
Chris@49 434 }
Chris@49 435
Chris@49 436
Chris@49 437
Chris@49 438 template<typename eT>
Chris@49 439 inline
Chris@49 440 SpMat<eT>::const_row_iterator::const_row_iterator(const SpMat<eT>& in_M, uword in_row, uword in_col)
Chris@49 441 : iterator_base(in_M, in_col, 0)
Chris@49 442 , internal_row(0)
Chris@49 443 , actual_pos(0)
Chris@49 444 {
Chris@49 445 // This is slow. It needs to be rewritten.
Chris@49 446 // So we have a destination we want to be just after, but don't know what position that is. Make another iterator to find out...
Chris@49 447 const_row_iterator it(in_M, 0);
Chris@49 448 while((it.row() < in_row) || ((it.row() == in_row) && (it.col() < in_col)))
Chris@49 449 {
Chris@49 450 it++;
Chris@49 451 }
Chris@49 452
Chris@49 453 // Now that it is at the right place, take its position.
Chris@49 454 iterator_base::internal_col = it.internal_col;
Chris@49 455 iterator_base::internal_pos = it.internal_pos;
Chris@49 456 internal_row = it.internal_row;
Chris@49 457 actual_pos = it.actual_pos;
Chris@49 458 }
Chris@49 459
Chris@49 460
Chris@49 461
Chris@49 462 /**
Chris@49 463 * Initialize the const_row_iterator from another const_row_iterator.
Chris@49 464 */
Chris@49 465 template<typename eT>
Chris@49 466 inline
Chris@49 467 SpMat<eT>::const_row_iterator::const_row_iterator(const typename SpMat<eT>::const_row_iterator& other)
Chris@49 468 : iterator_base(other.M, other.internal_col, other.internal_pos)
Chris@49 469 , internal_row(other.internal_row)
Chris@49 470 , actual_pos(other.actual_pos)
Chris@49 471 {
Chris@49 472 // Nothing to do.
Chris@49 473 }
Chris@49 474
Chris@49 475
Chris@49 476
Chris@49 477 /**
Chris@49 478 * Increment the row_iterator.
Chris@49 479 */
Chris@49 480 template<typename eT>
Chris@49 481 inline
Chris@49 482 arma_hot
Chris@49 483 typename SpMat<eT>::const_row_iterator&
Chris@49 484 SpMat<eT>::const_row_iterator::operator++()
Chris@49 485 {
Chris@49 486 // We just need to find the next nonzero element.
Chris@49 487 iterator_base::internal_pos++;
Chris@49 488
Chris@49 489 if(iterator_base::internal_pos == iterator_base::M.n_nonzero)
Chris@49 490 {
Chris@49 491 internal_row = iterator_base::M.n_rows;
Chris@49 492 iterator_base::internal_col = 0;
Chris@49 493 actual_pos = iterator_base::M.n_nonzero;
Chris@49 494
Chris@49 495 return *this;
Chris@49 496 }
Chris@49 497
Chris@49 498 // Otherwise, we need to search.
Chris@49 499 uword cur_col = iterator_base::internal_col;
Chris@49 500 uword cur_row = internal_row;
Chris@49 501
Chris@49 502 while (true) // This loop is terminated from the inside.
Chris@49 503 {
Chris@49 504 // Increment the current column and see if we are now on a new row.
Chris@49 505 if (++cur_col == iterator_base::M.n_cols)
Chris@49 506 {
Chris@49 507 cur_col = 0;
Chris@49 508 cur_row++;
Chris@49 509 }
Chris@49 510
Chris@49 511 // Is there anything in this new column?
Chris@49 512 for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++)
Chris@49 513 {
Chris@49 514 if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row)
Chris@49 515 {
Chris@49 516 // We have successfully incremented.
Chris@49 517 internal_row = cur_row;
Chris@49 518 iterator_base::internal_col = cur_col;
Chris@49 519 actual_pos = iterator_base::M.col_ptrs[cur_col] + ind;
Chris@49 520
Chris@49 521 return *this; // Now we are done.
Chris@49 522 }
Chris@49 523 }
Chris@49 524 }
Chris@49 525 }
Chris@49 526
Chris@49 527
Chris@49 528
Chris@49 529 /**
Chris@49 530 * Increment the row_iterator (but do not return anything.
Chris@49 531 */
Chris@49 532 template<typename eT>
Chris@49 533 inline
Chris@49 534 arma_hot
Chris@49 535 typename SpMat<eT>::const_row_iterator
Chris@49 536 SpMat<eT>::const_row_iterator::operator++(int)
Chris@49 537 {
Chris@49 538 typename SpMat<eT>::const_row_iterator tmp(*this);
Chris@49 539
Chris@49 540 ++(*this);
Chris@49 541
Chris@49 542 return tmp;
Chris@49 543 }
Chris@49 544
Chris@49 545
Chris@49 546
Chris@49 547 /**
Chris@49 548 * Decrement the row_iterator.
Chris@49 549 */
Chris@49 550 template<typename eT>
Chris@49 551 inline
Chris@49 552 arma_hot
Chris@49 553 typename SpMat<eT>::const_row_iterator&
Chris@49 554 SpMat<eT>::const_row_iterator::operator--()
Chris@49 555 {
Chris@49 556 iterator_base::internal_pos--;
Chris@49 557
Chris@49 558 // We have to search backwards.
Chris@49 559 uword cur_col = iterator_base::internal_col;
Chris@49 560 uword cur_row = internal_row;
Chris@49 561
Chris@49 562 while (true) // This loop is terminated from the inside.
Chris@49 563 {
Chris@49 564 // Decrement the current column and see if we are now on a new row. This is a uword so a negativity check won't work.
Chris@49 565 if (--cur_col > iterator_base::M.n_cols /* this means it underflew */)
Chris@49 566 {
Chris@49 567 cur_col = iterator_base::M.n_cols - 1;
Chris@49 568 cur_row--;
Chris@49 569 }
Chris@49 570
Chris@49 571 // Is there anything in this new column?
Chris@49 572 for (uword ind = 0; ((iterator_base::M.col_ptrs[cur_col] + ind < iterator_base::M.col_ptrs[cur_col + 1]) && (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] <= cur_row)); ind++)
Chris@49 573 {
Chris@49 574 if (iterator_base::M.row_indices[iterator_base::M.col_ptrs[cur_col] + ind] == cur_row)
Chris@49 575 {
Chris@49 576 // We have successfully decremented.
Chris@49 577 iterator_base::internal_col = cur_col;
Chris@49 578 internal_row = cur_row;
Chris@49 579 actual_pos = iterator_base::M.col_ptrs[cur_col] + ind;
Chris@49 580
Chris@49 581 return *this; // Now we are done.
Chris@49 582 }
Chris@49 583 }
Chris@49 584 }
Chris@49 585 }
Chris@49 586
Chris@49 587
Chris@49 588
Chris@49 589 /**
Chris@49 590 * Decrement the row_iterator.
Chris@49 591 */
Chris@49 592 template<typename eT>
Chris@49 593 inline
Chris@49 594 arma_hot
Chris@49 595 typename SpMat<eT>::const_row_iterator
Chris@49 596 SpMat<eT>::const_row_iterator::operator--(int)
Chris@49 597 {
Chris@49 598 typename SpMat<eT>::const_row_iterator tmp(*this);
Chris@49 599
Chris@49 600 --(*this);
Chris@49 601
Chris@49 602 return tmp;
Chris@49 603 }
Chris@49 604
Chris@49 605
Chris@49 606
Chris@49 607 template<typename eT>
Chris@49 608 inline
Chris@49 609 arma_hot
Chris@49 610 bool
Chris@49 611 SpMat<eT>::const_row_iterator::operator==(const const_iterator& rhs) const
Chris@49 612 {
Chris@49 613 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 614 }
Chris@49 615
Chris@49 616
Chris@49 617
Chris@49 618 template<typename eT>
Chris@49 619 inline
Chris@49 620 arma_hot
Chris@49 621 bool
Chris@49 622 SpMat<eT>::const_row_iterator::operator!=(const const_iterator& rhs) const
Chris@49 623 {
Chris@49 624 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 625 }
Chris@49 626
Chris@49 627
Chris@49 628
Chris@49 629 template<typename eT>
Chris@49 630 inline
Chris@49 631 arma_hot
Chris@49 632 bool
Chris@49 633 SpMat<eT>::const_row_iterator::operator==(const typename SpSubview<eT>::const_iterator& rhs) const
Chris@49 634 {
Chris@49 635 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 636 }
Chris@49 637
Chris@49 638
Chris@49 639
Chris@49 640 template<typename eT>
Chris@49 641 inline
Chris@49 642 arma_hot
Chris@49 643 bool
Chris@49 644 SpMat<eT>::const_row_iterator::operator!=(const typename SpSubview<eT>::const_iterator& rhs) const
Chris@49 645 {
Chris@49 646 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 647 }
Chris@49 648
Chris@49 649
Chris@49 650
Chris@49 651 template<typename eT>
Chris@49 652 inline
Chris@49 653 arma_hot
Chris@49 654 bool
Chris@49 655 SpMat<eT>::const_row_iterator::operator==(const const_row_iterator& rhs) const
Chris@49 656 {
Chris@49 657 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 658 }
Chris@49 659
Chris@49 660
Chris@49 661
Chris@49 662 template<typename eT>
Chris@49 663 inline
Chris@49 664 arma_hot
Chris@49 665 bool
Chris@49 666 SpMat<eT>::const_row_iterator::operator!=(const const_row_iterator& rhs) const
Chris@49 667 {
Chris@49 668 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 669 }
Chris@49 670
Chris@49 671
Chris@49 672
Chris@49 673 template<typename eT>
Chris@49 674 inline
Chris@49 675 arma_hot
Chris@49 676 bool
Chris@49 677 SpMat<eT>::const_row_iterator::operator==(const typename SpSubview<eT>::const_row_iterator& rhs) const
Chris@49 678 {
Chris@49 679 return (rhs.row() == row()) && (rhs.col() == iterator_base::internal_col);
Chris@49 680 }
Chris@49 681
Chris@49 682
Chris@49 683
Chris@49 684 template<typename eT>
Chris@49 685 inline
Chris@49 686 arma_hot
Chris@49 687 bool
Chris@49 688 SpMat<eT>::const_row_iterator::operator!=(const typename SpSubview<eT>::const_row_iterator& rhs) const
Chris@49 689 {
Chris@49 690 return (rhs.row() != row()) || (rhs.col() != iterator_base::internal_col);
Chris@49 691 }
Chris@49 692
Chris@49 693
Chris@49 694
Chris@49 695 ///////////////////////////////////////////////////////////////////////////////
Chris@49 696 // SpMat::row_iterator implementation //
Chris@49 697 ///////////////////////////////////////////////////////////////////////////////
Chris@49 698
Chris@49 699 template<typename eT>
Chris@49 700 inline
Chris@49 701 arma_hot
Chris@49 702 SpValProxy<SpMat<eT> >
Chris@49 703 SpMat<eT>::row_iterator::operator*()
Chris@49 704 {
Chris@49 705 return SpValProxy<SpMat<eT> >(
Chris@49 706 const_row_iterator::internal_row,
Chris@49 707 iterator_base::internal_col,
Chris@49 708 access::rw(iterator_base::M),
Chris@49 709 &access::rw(iterator_base::M.values[const_row_iterator::actual_pos]));
Chris@49 710 }
Chris@49 711
Chris@49 712
Chris@49 713
Chris@49 714 template<typename eT>
Chris@49 715 inline
Chris@49 716 arma_hot
Chris@49 717 typename SpMat<eT>::row_iterator&
Chris@49 718 SpMat<eT>::row_iterator::operator++()
Chris@49 719 {
Chris@49 720 const_row_iterator::operator++();
Chris@49 721 return *this;
Chris@49 722 }
Chris@49 723
Chris@49 724
Chris@49 725
Chris@49 726 template<typename eT>
Chris@49 727 inline
Chris@49 728 arma_hot
Chris@49 729 typename SpMat<eT>::row_iterator
Chris@49 730 SpMat<eT>::row_iterator::operator++(int)
Chris@49 731 {
Chris@49 732 typename SpMat<eT>::row_iterator tmp(*this);
Chris@49 733
Chris@49 734 const_row_iterator::operator++();
Chris@49 735
Chris@49 736 return tmp;
Chris@49 737 }
Chris@49 738
Chris@49 739
Chris@49 740
Chris@49 741 template<typename eT>
Chris@49 742 inline
Chris@49 743 arma_hot
Chris@49 744 typename SpMat<eT>::row_iterator&
Chris@49 745 SpMat<eT>::row_iterator::operator--()
Chris@49 746 {
Chris@49 747 const_row_iterator::operator--();
Chris@49 748 return *this;
Chris@49 749 }
Chris@49 750
Chris@49 751
Chris@49 752
Chris@49 753 template<typename eT>
Chris@49 754 inline
Chris@49 755 arma_hot
Chris@49 756 typename SpMat<eT>::row_iterator
Chris@49 757 SpMat<eT>::row_iterator::operator--(int)
Chris@49 758 {
Chris@49 759 typename SpMat<eT>::row_iterator tmp(*this);
Chris@49 760
Chris@49 761 const_row_iterator::operator--();
Chris@49 762
Chris@49 763 return tmp;
Chris@49 764 }
Chris@49 765
Chris@49 766 //! @}