annotate armadillo-3.900.4/include/armadillo_bits/SpSubview_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
Chris@49 10 //! \addtogroup SpSubview
Chris@49 11 //! @{
Chris@49 12
Chris@49 13 template<typename eT>
Chris@49 14 arma_inline
Chris@49 15 SpSubview<eT>::SpSubview(const SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
Chris@49 16 : m(in_m)
Chris@49 17 , aux_row1(in_row1)
Chris@49 18 , aux_col1(in_col1)
Chris@49 19 , n_rows(in_n_rows)
Chris@49 20 , n_cols(in_n_cols)
Chris@49 21 , n_elem(in_n_rows * in_n_cols)
Chris@49 22 , n_nonzero(0)
Chris@49 23 {
Chris@49 24 arma_extra_debug_sigprint();
Chris@49 25
Chris@49 26 // There must be a O(1) way to do this
Chris@49 27 uword lend = m.col_ptrs[in_col1 + in_n_cols];
Chris@49 28 uword lend_row = in_row1 + in_n_rows;
Chris@49 29 uword count = 0;
Chris@49 30
Chris@49 31 for(uword i = m.col_ptrs[in_col1]; i < lend; ++i)
Chris@49 32 {
Chris@49 33 if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row)
Chris@49 34 {
Chris@49 35 ++count;
Chris@49 36 }
Chris@49 37 }
Chris@49 38
Chris@49 39 access::rw(n_nonzero) = count;
Chris@49 40 }
Chris@49 41
Chris@49 42
Chris@49 43
Chris@49 44 template<typename eT>
Chris@49 45 arma_inline
Chris@49 46 SpSubview<eT>::SpSubview(SpMat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
Chris@49 47 : m(in_m)
Chris@49 48 , aux_row1(in_row1)
Chris@49 49 , aux_col1(in_col1)
Chris@49 50 , n_rows(in_n_rows)
Chris@49 51 , n_cols(in_n_cols)
Chris@49 52 , n_elem(in_n_rows * in_n_cols)
Chris@49 53 , n_nonzero(0)
Chris@49 54 {
Chris@49 55 arma_extra_debug_sigprint();
Chris@49 56
Chris@49 57 // There must be a O(1) way to do this
Chris@49 58 uword lend = m.col_ptrs[in_col1 + in_n_cols];
Chris@49 59 uword lend_row = in_row1 + in_n_rows;
Chris@49 60 uword count = 0;
Chris@49 61
Chris@49 62 for(uword i = m.col_ptrs[in_col1]; i < lend; ++i)
Chris@49 63 {
Chris@49 64 if(m.row_indices[i] >= in_row1 && m.row_indices[i] < lend_row)
Chris@49 65 {
Chris@49 66 ++count;
Chris@49 67 }
Chris@49 68 }
Chris@49 69
Chris@49 70 access::rw(n_nonzero) = count;
Chris@49 71 }
Chris@49 72
Chris@49 73
Chris@49 74
Chris@49 75 template<typename eT>
Chris@49 76 inline
Chris@49 77 SpSubview<eT>::~SpSubview()
Chris@49 78 {
Chris@49 79 arma_extra_debug_sigprint();
Chris@49 80 }
Chris@49 81
Chris@49 82
Chris@49 83
Chris@49 84 template<typename eT>
Chris@49 85 inline
Chris@49 86 const SpSubview<eT>&
Chris@49 87 SpSubview<eT>::operator+=(const eT val)
Chris@49 88 {
Chris@49 89 arma_extra_debug_sigprint();
Chris@49 90
Chris@49 91 if(val == eT(0))
Chris@49 92 {
Chris@49 93 return *this;
Chris@49 94 }
Chris@49 95
Chris@49 96 const uword lstart_row = aux_row1;
Chris@49 97 const uword lend_row = aux_row1 + n_rows;
Chris@49 98
Chris@49 99 const uword lstart_col = aux_col1;
Chris@49 100 const uword lend_col = aux_col1 + n_cols;
Chris@49 101
Chris@49 102 const uword old_n_nonzero = m.n_nonzero;
Chris@49 103
Chris@49 104 // iterate over our part of the sparse matrix
Chris@49 105 for(uword lcol = lstart_col; lcol < lend_col; ++lcol)
Chris@49 106 for(uword lrow = lstart_row; lrow < lend_row; ++lrow)
Chris@49 107 {
Chris@49 108 access::rw(m).at(lrow, lcol) += val;
Chris@49 109 }
Chris@49 110
Chris@49 111 const uword new_n_nonzero = m.n_nonzero;
Chris@49 112
Chris@49 113 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 114
Chris@49 115 return *this;
Chris@49 116 }
Chris@49 117
Chris@49 118
Chris@49 119
Chris@49 120 template<typename eT>
Chris@49 121 inline
Chris@49 122 const SpSubview<eT>&
Chris@49 123 SpSubview<eT>::operator-=(const eT val)
Chris@49 124 {
Chris@49 125 arma_extra_debug_sigprint();
Chris@49 126
Chris@49 127 if(val == eT(0))
Chris@49 128 {
Chris@49 129 return *this;
Chris@49 130 }
Chris@49 131
Chris@49 132 const uword lstart_row = aux_row1;
Chris@49 133 const uword lend_row = aux_row1 + n_rows;
Chris@49 134
Chris@49 135 const uword lstart_col = aux_col1;
Chris@49 136 const uword lend_col = aux_col1 + n_cols;
Chris@49 137
Chris@49 138 const uword old_n_nonzero = m.n_nonzero;
Chris@49 139
Chris@49 140 for(uword lcol = lstart_col; lcol < lend_col; ++lcol)
Chris@49 141 for(uword lrow = lstart_row; lrow < lend_row; ++lrow)
Chris@49 142 {
Chris@49 143 access::rw(m).at(lrow, lcol) -= val;
Chris@49 144 }
Chris@49 145
Chris@49 146 const uword new_n_nonzero = m.n_nonzero;
Chris@49 147
Chris@49 148 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 149
Chris@49 150 return *this;
Chris@49 151 }
Chris@49 152
Chris@49 153
Chris@49 154
Chris@49 155 template<typename eT>
Chris@49 156 inline
Chris@49 157 const SpSubview<eT>&
Chris@49 158 SpSubview<eT>::operator*=(const eT val)
Chris@49 159 {
Chris@49 160 arma_extra_debug_sigprint();
Chris@49 161
Chris@49 162 if(val == eT(0))
Chris@49 163 {
Chris@49 164 // Turn it all into zeros.
Chris@49 165 for(iterator it(*this); it != end(); ++it)
Chris@49 166 {
Chris@49 167 (*it) = eT(0); // zero out the value.
Chris@49 168 it.internal_pos--;
Chris@49 169 }
Chris@49 170
Chris@49 171 return *this;
Chris@49 172 }
Chris@49 173
Chris@49 174 const uword lstart_row = aux_row1;
Chris@49 175 const uword lend_row = aux_row1 + n_rows;
Chris@49 176
Chris@49 177 const uword lstart_col = aux_col1;
Chris@49 178 const uword lend_col = aux_col1 + n_cols;
Chris@49 179
Chris@49 180 for(uword c = lstart_col; c < lend_col; ++c)
Chris@49 181 {
Chris@49 182 for(uword r = m.col_ptrs[c]; r < m.col_ptrs[c + 1]; ++r)
Chris@49 183 {
Chris@49 184 if(m.row_indices[r] >= lstart_row && m.row_indices[r] < lend_row)
Chris@49 185 {
Chris@49 186 access::rw(m.values[r]) *= val;
Chris@49 187 }
Chris@49 188 }
Chris@49 189 }
Chris@49 190
Chris@49 191 return *this;
Chris@49 192 }
Chris@49 193
Chris@49 194
Chris@49 195
Chris@49 196 template<typename eT>
Chris@49 197 inline
Chris@49 198 const SpSubview<eT>&
Chris@49 199 SpSubview<eT>::operator/=(const eT val)
Chris@49 200 {
Chris@49 201 arma_extra_debug_sigprint();
Chris@49 202
Chris@49 203 const uword lstart_col = aux_col1;
Chris@49 204 const uword lend_col = aux_col1 + n_cols;
Chris@49 205
Chris@49 206 const uword lstart_row = aux_row1;
Chris@49 207 const uword lend_row = aux_row1 + n_rows;
Chris@49 208
Chris@49 209 const uword old_n_nonzero = m.n_nonzero;
Chris@49 210
Chris@49 211 for(uword c = lstart_col; c < lend_col; ++c)
Chris@49 212 for(uword r = lstart_row; r < lend_row; ++r)
Chris@49 213 {
Chris@49 214 access::rw(m).at(r, c) /= val;
Chris@49 215 }
Chris@49 216
Chris@49 217 const uword new_n_nonzero = m.n_nonzero;
Chris@49 218
Chris@49 219 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 220
Chris@49 221 return *this;
Chris@49 222 }
Chris@49 223
Chris@49 224
Chris@49 225
Chris@49 226 template<typename eT>
Chris@49 227 template<typename T1>
Chris@49 228 inline
Chris@49 229 const SpSubview<eT>&
Chris@49 230 SpSubview<eT>::operator=(const Base<eT, T1>& x)
Chris@49 231 {
Chris@49 232 arma_extra_debug_sigprint();
Chris@49 233
Chris@49 234 const Proxy<T1> P(x.get_ref());
Chris@49 235
Chris@49 236 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "insert into sparse submatrix");
Chris@49 237
Chris@49 238 const uword old_n_nonzero = m.n_nonzero;
Chris@49 239
Chris@49 240 for(uword c = 0; c < n_cols; ++c)
Chris@49 241 {
Chris@49 242 for(uword r = 0; r < n_rows; ++r)
Chris@49 243 {
Chris@49 244 at(r, c) = P.at(r, c);
Chris@49 245 }
Chris@49 246 }
Chris@49 247
Chris@49 248 const uword new_n_nonzero = m.n_nonzero;
Chris@49 249
Chris@49 250 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 251
Chris@49 252 return *this;
Chris@49 253 }
Chris@49 254
Chris@49 255
Chris@49 256
Chris@49 257 template<typename eT>
Chris@49 258 template<typename T1>
Chris@49 259 inline
Chris@49 260 const SpSubview<eT>&
Chris@49 261 SpSubview<eT>::operator+=(const Base<eT, T1>& x)
Chris@49 262 {
Chris@49 263 arma_extra_debug_sigprint();
Chris@49 264
Chris@49 265 const Proxy<T1> P(x.get_ref());
Chris@49 266
Chris@49 267 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "addition");
Chris@49 268
Chris@49 269 const uword old_n_nonzero = m.n_nonzero;
Chris@49 270
Chris@49 271 for(uword c = 0; c < n_cols; ++c)
Chris@49 272 {
Chris@49 273 for(uword r = 0; r < n_rows; ++r)
Chris@49 274 {
Chris@49 275 at(r, c) += P.at(r, c);
Chris@49 276 }
Chris@49 277 }
Chris@49 278
Chris@49 279 const uword new_n_nonzero = m.n_nonzero;
Chris@49 280
Chris@49 281 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 282
Chris@49 283 return *this;
Chris@49 284 }
Chris@49 285
Chris@49 286
Chris@49 287
Chris@49 288 template<typename eT>
Chris@49 289 template<typename T1>
Chris@49 290 inline
Chris@49 291 const SpSubview<eT>&
Chris@49 292 SpSubview<eT>::operator-=(const Base<eT, T1>& x)
Chris@49 293 {
Chris@49 294 arma_extra_debug_sigprint();
Chris@49 295
Chris@49 296 const Proxy<T1> P(x.get_ref());
Chris@49 297
Chris@49 298 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "subtraction");
Chris@49 299
Chris@49 300 const uword old_n_nonzero = m.n_nonzero;
Chris@49 301
Chris@49 302 for(uword c = 0; c < n_cols; ++c)
Chris@49 303 {
Chris@49 304 for(uword r = 0; r < n_rows; ++r)
Chris@49 305 {
Chris@49 306 at(r, c) -= P.at(r, c);
Chris@49 307 }
Chris@49 308 }
Chris@49 309
Chris@49 310 const uword new_n_nonzero = m.n_nonzero;
Chris@49 311
Chris@49 312 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 313
Chris@49 314 return *this;
Chris@49 315 }
Chris@49 316
Chris@49 317
Chris@49 318
Chris@49 319 template<typename eT>
Chris@49 320 template<typename T1>
Chris@49 321 inline
Chris@49 322 const SpSubview<eT>&
Chris@49 323 SpSubview<eT>::operator*=(const Base<eT, T1>& x)
Chris@49 324 {
Chris@49 325 arma_extra_debug_sigprint();
Chris@49 326
Chris@49 327 const Proxy<T1> P(x.get_ref());
Chris@49 328
Chris@49 329 // Must be exactly the same size for this (we can't modify our own size).
Chris@49 330 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "matrix multiplication");
Chris@49 331
Chris@49 332 SpMat<eT> tmp(*this);
Chris@49 333 Mat<eT> other_tmp(x.get_ref());
Chris@49 334 tmp *= other_tmp;
Chris@49 335 operator=(tmp);
Chris@49 336
Chris@49 337 return *this;
Chris@49 338 }
Chris@49 339
Chris@49 340
Chris@49 341
Chris@49 342 template<typename eT>
Chris@49 343 template<typename T1>
Chris@49 344 inline
Chris@49 345 const SpSubview<eT>&
Chris@49 346 SpSubview<eT>::operator%=(const Base<eT, T1>& x)
Chris@49 347 {
Chris@49 348 arma_extra_debug_sigprint();
Chris@49 349
Chris@49 350 const Proxy<T1> P(x.get_ref());
Chris@49 351
Chris@49 352 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "element-wise multiplication");
Chris@49 353
Chris@49 354 const uword old_n_nonzero = m.n_nonzero;
Chris@49 355
Chris@49 356 for(iterator it(*this); it != end(); ++it)
Chris@49 357 {
Chris@49 358 (*it) *= P.at(it.row(), it.col());
Chris@49 359 if(P.at(it.row(), it.col()) == eT(0))
Chris@49 360 {
Chris@49 361 it.internal_pos--;
Chris@49 362 }
Chris@49 363 }
Chris@49 364
Chris@49 365 const uword new_n_nonzero = m.n_nonzero;
Chris@49 366
Chris@49 367 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 368
Chris@49 369 return *this;
Chris@49 370 }
Chris@49 371
Chris@49 372
Chris@49 373
Chris@49 374 template<typename eT>
Chris@49 375 template<typename T1>
Chris@49 376 inline
Chris@49 377 const SpSubview<eT>&
Chris@49 378 SpSubview<eT>::operator/=(const Base<eT, T1>& x)
Chris@49 379 {
Chris@49 380 arma_extra_debug_sigprint();
Chris@49 381
Chris@49 382 const Proxy<T1> P(x.get_ref());
Chris@49 383
Chris@49 384 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "element-wise division");
Chris@49 385
Chris@49 386 const uword old_n_nonzero = m.n_nonzero;
Chris@49 387
Chris@49 388 for(uword c = 0; c < n_cols; ++c)
Chris@49 389 {
Chris@49 390 for(uword r = 0; r < n_rows; ++r)
Chris@49 391 {
Chris@49 392 at(r, c) /= P.at(r, c);
Chris@49 393 }
Chris@49 394 }
Chris@49 395
Chris@49 396 const uword new_n_nonzero = m.n_nonzero;
Chris@49 397
Chris@49 398 access::rw(n_nonzero) += (new_n_nonzero - old_n_nonzero);
Chris@49 399
Chris@49 400 return *this;
Chris@49 401 }
Chris@49 402
Chris@49 403
Chris@49 404
Chris@49 405 template<typename eT>
Chris@49 406 inline
Chris@49 407 const SpSubview<eT>&
Chris@49 408 SpSubview<eT>::operator=(const SpSubview<eT>& x)
Chris@49 409 {
Chris@49 410 arma_extra_debug_sigprint();
Chris@49 411
Chris@49 412 arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "insertion into sparse submatrix");
Chris@49 413
Chris@49 414 const bool alias = ( &m == &(x.m) );
Chris@49 415
Chris@49 416 if(alias == false)
Chris@49 417 {
Chris@49 418 const_iterator cit = x.begin();
Chris@49 419 iterator it = begin();
Chris@49 420
Chris@49 421 while((cit != x.end()) || (it != end()))
Chris@49 422 {
Chris@49 423 if((cit.row() == it.row()) && (cit.col() == it.col()))
Chris@49 424 {
Chris@49 425 (*it) = (*cit);
Chris@49 426 ++it;
Chris@49 427 ++cit;
Chris@49 428 }
Chris@49 429 else
Chris@49 430 {
Chris@49 431 if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row() > it.row())))
Chris@49 432 {
Chris@49 433 // cit is "ahead"
Chris@49 434 (*it) = eT(0); // erase element
Chris@49 435 it.internal_pos--; // update iterator so it still works
Chris@49 436 ++it;
Chris@49 437 }
Chris@49 438 else
Chris@49 439 {
Chris@49 440 // it is "ahead"
Chris@49 441 at(cit.row(), cit.col()) = (*cit);
Chris@49 442 it.internal_pos++; // update iterator so it still works
Chris@49 443 ++cit;
Chris@49 444 }
Chris@49 445 }
Chris@49 446 }
Chris@49 447
Chris@49 448 access::rw(n_nonzero) = x.n_nonzero;
Chris@49 449 }
Chris@49 450 else
Chris@49 451 {
Chris@49 452 const SpMat<eT> tmp(x);
Chris@49 453
Chris@49 454 (*this).operator=(tmp);
Chris@49 455 }
Chris@49 456
Chris@49 457 return *this;
Chris@49 458 }
Chris@49 459
Chris@49 460
Chris@49 461
Chris@49 462 template<typename eT>
Chris@49 463 template<typename T1>
Chris@49 464 inline
Chris@49 465 const SpSubview<eT>&
Chris@49 466 SpSubview<eT>::operator=(const SpBase<eT, T1>& x)
Chris@49 467 {
Chris@49 468 arma_extra_debug_sigprint();
Chris@49 469
Chris@49 470 const SpProxy<T1> p(x.get_ref());
Chris@49 471
Chris@49 472 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "insertion into sparse submatrix");
Chris@49 473
Chris@49 474 if(p.is_alias(m) == false)
Chris@49 475 {
Chris@49 476 typename SpProxy<T1>::const_iterator_type cit = p.begin();
Chris@49 477 iterator it(*this);
Chris@49 478
Chris@49 479 while((cit != p.end()) || (it != end()))
Chris@49 480 {
Chris@49 481 if(cit == it) // at the same location
Chris@49 482 {
Chris@49 483 (*it) = (*cit);
Chris@49 484 ++it;
Chris@49 485 ++cit;
Chris@49 486 }
Chris@49 487 else
Chris@49 488 {
Chris@49 489 if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row() > it.row())))
Chris@49 490 {
Chris@49 491 // cit is "ahead"
Chris@49 492 (*it) = eT(0); // erase element
Chris@49 493 it.internal_pos--; // update iterator so it still works
Chris@49 494 ++it;
Chris@49 495 }
Chris@49 496 else
Chris@49 497 {
Chris@49 498 // it is "ahead"
Chris@49 499 at(cit.row(), cit.col()) = (*cit);
Chris@49 500 it.internal_pos++; // update iterator so it still works
Chris@49 501 ++cit;
Chris@49 502 }
Chris@49 503 }
Chris@49 504 }
Chris@49 505 }
Chris@49 506 else
Chris@49 507 {
Chris@49 508 const SpMat<eT> tmp(p.Q);
Chris@49 509
Chris@49 510 (*this).operator=(tmp);
Chris@49 511 }
Chris@49 512
Chris@49 513 return *this;
Chris@49 514 }
Chris@49 515
Chris@49 516
Chris@49 517
Chris@49 518 template<typename eT>
Chris@49 519 template<typename T1>
Chris@49 520 inline
Chris@49 521 const SpSubview<eT>&
Chris@49 522 SpSubview<eT>::operator+=(const SpBase<eT, T1>& x)
Chris@49 523 {
Chris@49 524 arma_extra_debug_sigprint();
Chris@49 525
Chris@49 526 const SpProxy<T1> p(x.get_ref());
Chris@49 527
Chris@49 528 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
Chris@49 529
Chris@49 530 if(p.is_alias(m) == false)
Chris@49 531 {
Chris@49 532 typename SpProxy<T1>::const_iterator_type cit = p.begin();
Chris@49 533
Chris@49 534 while(cit != p.end())
Chris@49 535 {
Chris@49 536 at(cit.row(), cit.col()) += (*cit);
Chris@49 537 ++cit;
Chris@49 538 }
Chris@49 539 }
Chris@49 540 else
Chris@49 541 {
Chris@49 542 const SpMat<eT> tmp(p.Q);
Chris@49 543
Chris@49 544 (*this).operator+=(tmp);
Chris@49 545 }
Chris@49 546
Chris@49 547 return *this;
Chris@49 548 }
Chris@49 549
Chris@49 550
Chris@49 551
Chris@49 552 template<typename eT>
Chris@49 553 template<typename T1>
Chris@49 554 inline
Chris@49 555 const SpSubview<eT>&
Chris@49 556 SpSubview<eT>::operator-=(const SpBase<eT, T1>& x)
Chris@49 557 {
Chris@49 558 arma_extra_debug_sigprint();
Chris@49 559
Chris@49 560 const SpProxy<T1> p(x.get_ref());
Chris@49 561
Chris@49 562 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
Chris@49 563
Chris@49 564 if(p.is_alias(m) == false)
Chris@49 565 {
Chris@49 566 typename SpProxy<T1>::const_iterator_type cit = p.begin();
Chris@49 567
Chris@49 568 while(cit != p.end())
Chris@49 569 {
Chris@49 570 at(cit.row(), cit.col()) -= (*cit);
Chris@49 571 ++cit;
Chris@49 572 }
Chris@49 573 }
Chris@49 574 else
Chris@49 575 {
Chris@49 576 const SpMat<eT> tmp(p.Q);
Chris@49 577
Chris@49 578 (*this).operator-=(tmp);
Chris@49 579 }
Chris@49 580
Chris@49 581 return *this;
Chris@49 582 }
Chris@49 583
Chris@49 584
Chris@49 585
Chris@49 586 template<typename eT>
Chris@49 587 template<typename T1>
Chris@49 588 inline
Chris@49 589 const SpSubview<eT>&
Chris@49 590 SpSubview<eT>::operator*=(const SpBase<eT, T1>& x)
Chris@49 591 {
Chris@49 592 arma_extra_debug_sigprint();
Chris@49 593
Chris@49 594 const SpProxy<T1> p(x.get_ref());
Chris@49 595
Chris@49 596 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "matrix multiplication");
Chris@49 597
Chris@49 598 // Because we have to use a temporary anyway, it doesn't make sense to
Chris@49 599 // reimplement this here.
Chris@49 600 return operator=((*this) * x.get_ref());
Chris@49 601 }
Chris@49 602
Chris@49 603
Chris@49 604
Chris@49 605 template<typename eT>
Chris@49 606 template<typename T1>
Chris@49 607 inline
Chris@49 608 const SpSubview<eT>&
Chris@49 609 SpSubview<eT>::operator%=(const SpBase<eT, T1>& x)
Chris@49 610 {
Chris@49 611 arma_extra_debug_sigprint();
Chris@49 612
Chris@49 613 const SpProxy<T1> p(x.get_ref());
Chris@49 614
Chris@49 615 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication");
Chris@49 616
Chris@49 617 if(p.is_alias(m) == false)
Chris@49 618 {
Chris@49 619 typename SpProxy<T1>::const_iterator_type cit = p.begin();
Chris@49 620 iterator it(*this);
Chris@49 621
Chris@49 622 while((it != end()) || (cit != p.end()))
Chris@49 623 {
Chris@49 624 if((cit.row() == it.row()) && (cit.col() == it.col()))
Chris@49 625 {
Chris@49 626 (*it) *= (*cit);
Chris@49 627 ++it;
Chris@49 628 ++cit;
Chris@49 629 }
Chris@49 630 else
Chris@49 631 {
Chris@49 632 if((cit.col() > it.col()) || ((cit.col() == it.col()) && (cit.row() > it.row())))
Chris@49 633 {
Chris@49 634 // cit is "ahead"
Chris@49 635 (*it) = eT(0); // erase element -- x has a zero here
Chris@49 636 it.internal_pos--; // update iterator so it still works
Chris@49 637 ++it;
Chris@49 638 }
Chris@49 639 else
Chris@49 640 {
Chris@49 641 // it is "ahead"
Chris@49 642 ++cit;
Chris@49 643 }
Chris@49 644 }
Chris@49 645 }
Chris@49 646 }
Chris@49 647 else
Chris@49 648 {
Chris@49 649 const SpMat<eT> tmp(p.Q);
Chris@49 650
Chris@49 651 (*this).operator%=(tmp);
Chris@49 652 }
Chris@49 653
Chris@49 654 return *this;
Chris@49 655 }
Chris@49 656
Chris@49 657
Chris@49 658
Chris@49 659 //! If you are using this function, you are probably misguided.
Chris@49 660 template<typename eT>
Chris@49 661 template<typename T1>
Chris@49 662 inline
Chris@49 663 const SpSubview<eT>&
Chris@49 664 SpSubview<eT>::operator/=(const SpBase<eT, T1>& x)
Chris@49 665 {
Chris@49 666 arma_extra_debug_sigprint();
Chris@49 667
Chris@49 668 SpProxy<T1> p(x.get_ref());
Chris@49 669
Chris@49 670 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
Chris@49 671
Chris@49 672 if(p.is_alias(m) == false)
Chris@49 673 {
Chris@49 674 for(uword lcol = 0; lcol < n_cols; ++lcol)
Chris@49 675 for(uword lrow = 0; lrow < n_rows; ++lrow)
Chris@49 676 {
Chris@49 677 at(lrow,lcol) /= p.at(lrow,lcol);
Chris@49 678 }
Chris@49 679 }
Chris@49 680 else
Chris@49 681 {
Chris@49 682 const SpMat<eT> tmp(p.Q);
Chris@49 683
Chris@49 684 (*this).operator/=(tmp);
Chris@49 685 }
Chris@49 686
Chris@49 687 return *this;
Chris@49 688 }
Chris@49 689
Chris@49 690
Chris@49 691
Chris@49 692 template<typename eT>
Chris@49 693 inline
Chris@49 694 void
Chris@49 695 SpSubview<eT>::fill(const eT val)
Chris@49 696 {
Chris@49 697 arma_extra_debug_sigprint();
Chris@49 698
Chris@49 699 if(val != eT(0))
Chris@49 700 {
Chris@49 701 // TODO: implement a faster version; the code below is slow
Chris@49 702
Chris@49 703 const uword lstart_row = aux_row1;
Chris@49 704 const uword lend_row = aux_row1 + n_rows;
Chris@49 705
Chris@49 706 const uword lstart_col = aux_col1;
Chris@49 707 const uword lend_col = aux_col1 + n_cols;
Chris@49 708
Chris@49 709 const uword orig_nonzero = m.n_nonzero;
Chris@49 710
Chris@49 711 // iterate over our part of the sparse matrix
Chris@49 712 for(uword lcol = lstart_col; lcol < lend_col; ++lcol)
Chris@49 713 for(uword lrow = lstart_row; lrow < lend_row; ++lrow)
Chris@49 714 {
Chris@49 715 access::rw(m).at(lrow, lcol) = val;
Chris@49 716 }
Chris@49 717
Chris@49 718 access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero);
Chris@49 719
Chris@49 720 }
Chris@49 721 else
Chris@49 722 {
Chris@49 723 (*this).zeros();
Chris@49 724 }
Chris@49 725 }
Chris@49 726
Chris@49 727
Chris@49 728
Chris@49 729 template<typename eT>
Chris@49 730 inline
Chris@49 731 void
Chris@49 732 SpSubview<eT>::zeros()
Chris@49 733 {
Chris@49 734 arma_extra_debug_sigprint();
Chris@49 735
Chris@49 736 // we can be a little smarter here
Chris@49 737 iterator it(*this);
Chris@49 738
Chris@49 739 while(it != end())
Chris@49 740 {
Chris@49 741 (*it) = eT(0);
Chris@49 742 it.internal_pos--; // hack to update iterator without requiring a new one
Chris@49 743 ++it;
Chris@49 744 }
Chris@49 745 }
Chris@49 746
Chris@49 747
Chris@49 748
Chris@49 749 template<typename eT>
Chris@49 750 inline
Chris@49 751 void
Chris@49 752 SpSubview<eT>::ones()
Chris@49 753 {
Chris@49 754 arma_extra_debug_sigprint();
Chris@49 755
Chris@49 756 (*this).fill(eT(1));
Chris@49 757 }
Chris@49 758
Chris@49 759
Chris@49 760
Chris@49 761 template<typename eT>
Chris@49 762 inline
Chris@49 763 void
Chris@49 764 SpSubview<eT>::eye()
Chris@49 765 {
Chris@49 766 arma_extra_debug_sigprint();
Chris@49 767
Chris@49 768 // clear other things
Chris@49 769 (*this).zeros();
Chris@49 770
Chris@49 771 const uword orig_nonzero = m.n_nonzero;
Chris@49 772
Chris@49 773 // now the diagonal ones
Chris@49 774 const uword end_index = std::min(n_rows, n_cols);
Chris@49 775
Chris@49 776 for(uword ind = 0; ind < end_index; ++ind)
Chris@49 777 {
Chris@49 778 access::rw(m).at(ind + aux_row1, ind + aux_col1) = eT(1);
Chris@49 779 }
Chris@49 780
Chris@49 781 access::rw(n_nonzero) += (m.n_nonzero - orig_nonzero);
Chris@49 782 }
Chris@49 783
Chris@49 784
Chris@49 785
Chris@49 786 template<typename eT>
Chris@49 787 arma_hot
Chris@49 788 inline
Chris@49 789 SpValProxy<SpSubview<eT> >
Chris@49 790 SpSubview<eT>::operator[](const uword i)
Chris@49 791 {
Chris@49 792 const uword lrow = i % n_rows;
Chris@49 793 const uword lcol = i / n_rows;
Chris@49 794
Chris@49 795 return (*this).at(lrow, lcol);
Chris@49 796 }
Chris@49 797
Chris@49 798
Chris@49 799
Chris@49 800 template<typename eT>
Chris@49 801 arma_hot
Chris@49 802 inline
Chris@49 803 eT
Chris@49 804 SpSubview<eT>::operator[](const uword i) const
Chris@49 805 {
Chris@49 806 const uword lrow = i % n_rows;
Chris@49 807 const uword lcol = i / n_rows;
Chris@49 808
Chris@49 809 return (*this).at(lrow, lcol);
Chris@49 810 }
Chris@49 811
Chris@49 812
Chris@49 813
Chris@49 814 template<typename eT>
Chris@49 815 arma_hot
Chris@49 816 inline
Chris@49 817 SpValProxy< SpSubview<eT> >
Chris@49 818 SpSubview<eT>::operator()(const uword i)
Chris@49 819 {
Chris@49 820 arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bounds");
Chris@49 821
Chris@49 822 const uword lrow = i % n_rows;
Chris@49 823 const uword lcol = i / n_rows;
Chris@49 824
Chris@49 825 return (*this).at(lrow, lcol);
Chris@49 826 }
Chris@49 827
Chris@49 828
Chris@49 829
Chris@49 830 template<typename eT>
Chris@49 831 arma_hot
Chris@49 832 inline
Chris@49 833 eT
Chris@49 834 SpSubview<eT>::operator()(const uword i) const
Chris@49 835 {
Chris@49 836 arma_debug_check( (i >= n_elem), "SpSubview::operator(): index out of bounds");
Chris@49 837
Chris@49 838 const uword lrow = i % n_rows;
Chris@49 839 const uword lcol = i / n_rows;
Chris@49 840
Chris@49 841 return (*this).at(lrow, lcol);
Chris@49 842 }
Chris@49 843
Chris@49 844
Chris@49 845
Chris@49 846 template<typename eT>
Chris@49 847 arma_hot
Chris@49 848 inline
Chris@49 849 SpValProxy< SpSubview<eT> >
Chris@49 850 SpSubview<eT>::operator()(const uword in_row, const uword in_col)
Chris@49 851 {
Chris@49 852 arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds");
Chris@49 853
Chris@49 854 return (*this).at(in_row, in_col);
Chris@49 855 }
Chris@49 856
Chris@49 857
Chris@49 858
Chris@49 859 template<typename eT>
Chris@49 860 arma_hot
Chris@49 861 inline
Chris@49 862 eT
Chris@49 863 SpSubview<eT>::operator()(const uword in_row, const uword in_col) const
Chris@49 864 {
Chris@49 865 arma_debug_check( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds");
Chris@49 866
Chris@49 867 return (*this).at(in_row, in_col);
Chris@49 868 }
Chris@49 869
Chris@49 870
Chris@49 871
Chris@49 872 template<typename eT>
Chris@49 873 arma_hot
Chris@49 874 inline
Chris@49 875 SpValProxy< SpSubview<eT> >
Chris@49 876 SpSubview<eT>::at(const uword i)
Chris@49 877 {
Chris@49 878 const uword lrow = i % n_rows;
Chris@49 879 const uword lcol = i / n_cols;
Chris@49 880
Chris@49 881 return (*this).at(lrow, lcol);
Chris@49 882 }
Chris@49 883
Chris@49 884
Chris@49 885
Chris@49 886 template<typename eT>
Chris@49 887 arma_hot
Chris@49 888 inline
Chris@49 889 eT
Chris@49 890 SpSubview<eT>::at(const uword i) const
Chris@49 891 {
Chris@49 892 const uword lrow = i % n_rows;
Chris@49 893 const uword lcol = i / n_cols;
Chris@49 894
Chris@49 895 return (*this).at(lrow, lcol);
Chris@49 896 }
Chris@49 897
Chris@49 898
Chris@49 899
Chris@49 900 template<typename eT>
Chris@49 901 arma_hot
Chris@49 902 inline
Chris@49 903 SpValProxy< SpSubview<eT> >
Chris@49 904 SpSubview<eT>::at(const uword in_row, const uword in_col)
Chris@49 905 {
Chris@49 906 const uword colptr = m.col_ptrs[in_col + aux_col1];
Chris@49 907 const uword next_colptr = m.col_ptrs[in_col + aux_col1 + 1];
Chris@49 908
Chris@49 909 // Step through the row indices to see if our element exists.
Chris@49 910 for(uword i = colptr; i < next_colptr; ++i)
Chris@49 911 {
Chris@49 912 // First check that we have not stepped past it.
Chris@49 913 if((in_row + aux_row1) < m.row_indices[i])
Chris@49 914 {
Chris@49 915 return SpValProxy<SpSubview<eT> >(in_row, in_col, *this); // Proxy for a zero value.
Chris@49 916 }
Chris@49 917
Chris@49 918 // Now check if we are at the correct place.
Chris@49 919 if((in_row + aux_row1) == m.row_indices[i]) // If we are, return a reference to the value.
Chris@49 920 {
Chris@49 921 return SpValProxy<SpSubview<eT> >(in_row, in_col, *this, &access::rw(m.values[i]));
Chris@49 922 }
Chris@49 923 }
Chris@49 924
Chris@49 925 // We did not find it, so it does not exist.
Chris@49 926 return SpValProxy<SpSubview<eT> >(in_row, in_col, *this);
Chris@49 927 }
Chris@49 928
Chris@49 929
Chris@49 930
Chris@49 931 template<typename eT>
Chris@49 932 arma_hot
Chris@49 933 inline
Chris@49 934 eT
Chris@49 935 SpSubview<eT>::at(const uword in_row, const uword in_col) const
Chris@49 936 {
Chris@49 937 return m.at(aux_row1 + in_row, aux_col1 + in_col);
Chris@49 938 }
Chris@49 939
Chris@49 940
Chris@49 941
Chris@49 942 template<typename eT>
Chris@49 943 inline
Chris@49 944 bool
Chris@49 945 SpSubview<eT>::check_overlap(const SpSubview<eT>& x) const
Chris@49 946 {
Chris@49 947 const subview<eT>& t = *this;
Chris@49 948
Chris@49 949 if(&t.m != &x.m)
Chris@49 950 {
Chris@49 951 return false;
Chris@49 952 }
Chris@49 953 else
Chris@49 954 {
Chris@49 955 if( (t.n_elem == 0) || (x.n_elem == 0) )
Chris@49 956 {
Chris@49 957 return false;
Chris@49 958 }
Chris@49 959 else
Chris@49 960 {
Chris@49 961 const uword t_row_start = t.aux_row1;
Chris@49 962 const uword t_row_end_p1 = t_row_start + t.n_rows;
Chris@49 963
Chris@49 964 const uword t_col_start = t.aux_col1;
Chris@49 965 const uword t_col_end_p1 = t_col_start + t.n_cols;
Chris@49 966
Chris@49 967 const uword x_row_start = x.aux_row1;
Chris@49 968 const uword x_row_end_p1 = x_row_start + x.n_rows;
Chris@49 969
Chris@49 970 const uword x_col_start = x.aux_col1;
Chris@49 971 const uword x_col_end_p1 = x_col_start + x.n_cols;
Chris@49 972
Chris@49 973 const bool outside_rows = ( (x_row_start >= t_row_end_p1) || (t_row_start >= x_row_end_p1) );
Chris@49 974 const bool outside_cols = ( (x_col_start >= t_col_end_p1) || (t_col_start >= x_col_end_p1) );
Chris@49 975
Chris@49 976 return ( (outside_rows == false) && (outside_cols == false) );
Chris@49 977 }
Chris@49 978 }
Chris@49 979 }
Chris@49 980
Chris@49 981
Chris@49 982
Chris@49 983 template<typename eT>
Chris@49 984 inline
Chris@49 985 bool
Chris@49 986 SpSubview<eT>::is_vec() const
Chris@49 987 {
Chris@49 988 return ( (n_rows == 1) || (n_cols == 1) );
Chris@49 989 }
Chris@49 990
Chris@49 991
Chris@49 992
Chris@49 993 template<typename eT>
Chris@49 994 inline
Chris@49 995 SpSubview<eT>
Chris@49 996 SpSubview<eT>::row(const uword row_num)
Chris@49 997 {
Chris@49 998 arma_extra_debug_sigprint();
Chris@49 999
Chris@49 1000 arma_debug_check(row_num >= n_rows, "SpSubview::row(): out of bounds");
Chris@49 1001
Chris@49 1002 return submat(row_num, 0, row_num, n_cols - 1);
Chris@49 1003 }
Chris@49 1004
Chris@49 1005
Chris@49 1006
Chris@49 1007 template<typename eT>
Chris@49 1008 inline
Chris@49 1009 const SpSubview<eT>
Chris@49 1010 SpSubview<eT>::row(const uword row_num) const
Chris@49 1011 {
Chris@49 1012 arma_extra_debug_sigprint();
Chris@49 1013
Chris@49 1014 arma_debug_check(row_num >= n_rows, "SpSubview::row(): out of bounds");
Chris@49 1015
Chris@49 1016 return submat(row_num, 0, row_num, n_cols - 1);
Chris@49 1017 }
Chris@49 1018
Chris@49 1019
Chris@49 1020
Chris@49 1021 template<typename eT>
Chris@49 1022 inline
Chris@49 1023 SpSubview<eT>
Chris@49 1024 SpSubview<eT>::col(const uword col_num)
Chris@49 1025 {
Chris@49 1026 arma_extra_debug_sigprint();
Chris@49 1027
Chris@49 1028 arma_debug_check(col_num >= n_cols, "SpSubview::col(): out of bounds");
Chris@49 1029
Chris@49 1030 return submat(0, col_num, n_rows - 1, col_num);
Chris@49 1031 }
Chris@49 1032
Chris@49 1033
Chris@49 1034
Chris@49 1035 template<typename eT>
Chris@49 1036 inline
Chris@49 1037 const SpSubview<eT>
Chris@49 1038 SpSubview<eT>::col(const uword col_num) const
Chris@49 1039 {
Chris@49 1040 arma_extra_debug_sigprint();
Chris@49 1041
Chris@49 1042 arma_debug_check(col_num >= n_cols, "SpSubview::col(): out of bounds");
Chris@49 1043
Chris@49 1044 return submat(0, col_num, n_rows - 1, col_num);
Chris@49 1045 }
Chris@49 1046
Chris@49 1047
Chris@49 1048
Chris@49 1049 template<typename eT>
Chris@49 1050 inline
Chris@49 1051 SpSubview<eT>
Chris@49 1052 SpSubview<eT>::rows(const uword in_row1, const uword in_row2)
Chris@49 1053 {
Chris@49 1054 arma_extra_debug_sigprint();
Chris@49 1055
Chris@49 1056 arma_debug_check
Chris@49 1057 (
Chris@49 1058 (in_row1 > in_row2) || (in_row2 >= n_rows),
Chris@49 1059 "SpSubview::rows(): indices out of bounds or incorrectly used"
Chris@49 1060 );
Chris@49 1061
Chris@49 1062 return submat(in_row1, 0, in_row2, n_cols - 1);
Chris@49 1063 }
Chris@49 1064
Chris@49 1065
Chris@49 1066
Chris@49 1067 template<typename eT>
Chris@49 1068 inline
Chris@49 1069 const SpSubview<eT>
Chris@49 1070 SpSubview<eT>::rows(const uword in_row1, const uword in_row2) const
Chris@49 1071 {
Chris@49 1072 arma_extra_debug_sigprint();
Chris@49 1073
Chris@49 1074 arma_debug_check
Chris@49 1075 (
Chris@49 1076 (in_row1 > in_row2) || (in_row2 >= n_rows),
Chris@49 1077 "SpSubview::rows(): indices out of bounds or incorrectly used"
Chris@49 1078 );
Chris@49 1079
Chris@49 1080 return submat(in_row1, 0, in_row2, n_cols - 1);
Chris@49 1081 }
Chris@49 1082
Chris@49 1083
Chris@49 1084
Chris@49 1085 template<typename eT>
Chris@49 1086 inline
Chris@49 1087 SpSubview<eT>
Chris@49 1088 SpSubview<eT>::cols(const uword in_col1, const uword in_col2)
Chris@49 1089 {
Chris@49 1090 arma_extra_debug_sigprint();
Chris@49 1091
Chris@49 1092 arma_debug_check
Chris@49 1093 (
Chris@49 1094 (in_col1 > in_col2) || (in_col2 >= n_cols),
Chris@49 1095 "SpSubview::cols(): indices out of bounds or incorrectly used"
Chris@49 1096 );
Chris@49 1097
Chris@49 1098 return submat(0, in_col1, n_rows - 1, in_col2);
Chris@49 1099 }
Chris@49 1100
Chris@49 1101
Chris@49 1102
Chris@49 1103 template<typename eT>
Chris@49 1104 inline
Chris@49 1105 const SpSubview<eT>
Chris@49 1106 SpSubview<eT>::cols(const uword in_col1, const uword in_col2) const
Chris@49 1107 {
Chris@49 1108 arma_extra_debug_sigprint();
Chris@49 1109
Chris@49 1110 arma_debug_check
Chris@49 1111 (
Chris@49 1112 (in_col1 > in_col2) || (in_col2 >= n_cols),
Chris@49 1113 "SpSubview::cols(): indices out of bounds or incorrectly used"
Chris@49 1114 );
Chris@49 1115
Chris@49 1116 return submat(0, in_col1, n_rows - 1, in_col2);
Chris@49 1117 }
Chris@49 1118
Chris@49 1119
Chris@49 1120
Chris@49 1121 template<typename eT>
Chris@49 1122 inline
Chris@49 1123 SpSubview<eT>
Chris@49 1124 SpSubview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
Chris@49 1125 {
Chris@49 1126 arma_extra_debug_sigprint();
Chris@49 1127
Chris@49 1128 arma_debug_check
Chris@49 1129 (
Chris@49 1130 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
Chris@49 1131 "SpSubview::submat(): indices out of bounds or incorrectly used"
Chris@49 1132 );
Chris@49 1133
Chris@49 1134 return access::rw(m).submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1);
Chris@49 1135 }
Chris@49 1136
Chris@49 1137
Chris@49 1138
Chris@49 1139 template<typename eT>
Chris@49 1140 inline
Chris@49 1141 const SpSubview<eT>
Chris@49 1142 SpSubview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
Chris@49 1143 {
Chris@49 1144 arma_extra_debug_sigprint();
Chris@49 1145
Chris@49 1146 arma_debug_check
Chris@49 1147 (
Chris@49 1148 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
Chris@49 1149 "SpSubview::submat(): indices out of bounds or incorrectly used"
Chris@49 1150 );
Chris@49 1151
Chris@49 1152 return m.submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1);
Chris@49 1153 }
Chris@49 1154
Chris@49 1155
Chris@49 1156
Chris@49 1157 template<typename eT>
Chris@49 1158 inline
Chris@49 1159 SpSubview<eT>
Chris@49 1160 SpSubview<eT>::submat(const span& row_span, const span& col_span)
Chris@49 1161 {
Chris@49 1162 arma_extra_debug_sigprint();
Chris@49 1163
Chris@49 1164 const bool row_all = row_span.whole;
Chris@49 1165 const bool col_all = row_span.whole;
Chris@49 1166
Chris@49 1167 const uword in_row1 = row_all ? 0 : row_span.a;
Chris@49 1168 const uword in_row2 = row_all ? n_rows : row_span.b;
Chris@49 1169
Chris@49 1170 const uword in_col1 = col_all ? 0 : col_span.a;
Chris@49 1171 const uword in_col2 = col_all ? n_cols : col_span.b;
Chris@49 1172
Chris@49 1173 arma_debug_check
Chris@49 1174 (
Chris@49 1175 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows)))
Chris@49 1176 ||
Chris@49 1177 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))),
Chris@49 1178 "SpSubview::submat(): indices out of bounds or incorrectly used"
Chris@49 1179 );
Chris@49 1180
Chris@49 1181 return submat(in_row1, in_col1, in_row2, in_col2);
Chris@49 1182 }
Chris@49 1183
Chris@49 1184
Chris@49 1185
Chris@49 1186 template<typename eT>
Chris@49 1187 inline
Chris@49 1188 const SpSubview<eT>
Chris@49 1189 SpSubview<eT>::submat(const span& row_span, const span& col_span) const
Chris@49 1190 {
Chris@49 1191 arma_extra_debug_sigprint();
Chris@49 1192
Chris@49 1193 const bool row_all = row_span.whole;
Chris@49 1194 const bool col_all = row_span.whole;
Chris@49 1195
Chris@49 1196 const uword in_row1 = row_all ? 0 : row_span.a;
Chris@49 1197 const uword in_row2 = row_all ? n_rows - 1 : row_span.b;
Chris@49 1198
Chris@49 1199 const uword in_col1 = col_all ? 0 : col_span.a;
Chris@49 1200 const uword in_col2 = col_all ? n_cols - 1 : col_span.b;
Chris@49 1201
Chris@49 1202 arma_debug_check
Chris@49 1203 (
Chris@49 1204 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows)))
Chris@49 1205 ||
Chris@49 1206 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))),
Chris@49 1207 "SpSubview::submat(): indices out of bounds or incorrectly used"
Chris@49 1208 );
Chris@49 1209
Chris@49 1210 return submat(in_row1, in_col1, in_row2, in_col2);
Chris@49 1211 }
Chris@49 1212
Chris@49 1213
Chris@49 1214
Chris@49 1215 template<typename eT>
Chris@49 1216 inline
Chris@49 1217 SpSubview<eT>
Chris@49 1218 SpSubview<eT>::operator()(const uword row_num, const span& col_span)
Chris@49 1219 {
Chris@49 1220 arma_extra_debug_sigprint();
Chris@49 1221
Chris@49 1222 return submat(span(row_num, row_num), col_span);
Chris@49 1223 }
Chris@49 1224
Chris@49 1225
Chris@49 1226
Chris@49 1227 template<typename eT>
Chris@49 1228 inline
Chris@49 1229 const SpSubview<eT>
Chris@49 1230 SpSubview<eT>::operator()(const uword row_num, const span& col_span) const
Chris@49 1231 {
Chris@49 1232 arma_extra_debug_sigprint();
Chris@49 1233
Chris@49 1234 return submat(span(row_num, row_num), col_span);
Chris@49 1235 }
Chris@49 1236
Chris@49 1237
Chris@49 1238
Chris@49 1239 template<typename eT>
Chris@49 1240 inline
Chris@49 1241 SpSubview<eT>
Chris@49 1242 SpSubview<eT>::operator()(const span& row_span, const uword col_num)
Chris@49 1243 {
Chris@49 1244 arma_extra_debug_sigprint();
Chris@49 1245
Chris@49 1246 return submat(row_span, span(col_num, col_num));
Chris@49 1247 }
Chris@49 1248
Chris@49 1249
Chris@49 1250
Chris@49 1251 template<typename eT>
Chris@49 1252 inline
Chris@49 1253 const SpSubview<eT>
Chris@49 1254 SpSubview<eT>::operator()(const span& row_span, const uword col_num) const
Chris@49 1255 {
Chris@49 1256 arma_extra_debug_sigprint();
Chris@49 1257
Chris@49 1258 return submat(row_span, span(col_num, col_num));
Chris@49 1259 }
Chris@49 1260
Chris@49 1261
Chris@49 1262
Chris@49 1263 template<typename eT>
Chris@49 1264 inline
Chris@49 1265 SpSubview<eT>
Chris@49 1266 SpSubview<eT>::operator()(const span& row_span, const span& col_span)
Chris@49 1267 {
Chris@49 1268 arma_extra_debug_sigprint();
Chris@49 1269
Chris@49 1270 return submat(row_span, col_span);
Chris@49 1271 }
Chris@49 1272
Chris@49 1273
Chris@49 1274
Chris@49 1275 template<typename eT>
Chris@49 1276 inline
Chris@49 1277 const SpSubview<eT>
Chris@49 1278 SpSubview<eT>::operator()(const span& row_span, const span& col_span) const
Chris@49 1279 {
Chris@49 1280 arma_extra_debug_sigprint();
Chris@49 1281
Chris@49 1282 return submat(row_span, col_span);
Chris@49 1283 }
Chris@49 1284
Chris@49 1285
Chris@49 1286
Chris@49 1287 template<typename eT>
Chris@49 1288 inline
Chris@49 1289 void
Chris@49 1290 SpSubview<eT>::swap_rows(const uword in_row1, const uword in_row2)
Chris@49 1291 {
Chris@49 1292 arma_extra_debug_sigprint();
Chris@49 1293
Chris@49 1294 arma_debug_check((in_row1 >= n_rows) || (in_row2 >= n_rows), "SpSubview::swap_rows(): invalid row index");
Chris@49 1295
Chris@49 1296 const uword lstart_col = aux_col1;
Chris@49 1297 const uword lend_col = aux_col1 + n_cols;
Chris@49 1298
Chris@49 1299 for(uword c = lstart_col; c < lend_col; ++c)
Chris@49 1300 {
Chris@49 1301 eT val = m.at(in_row1 + aux_row1, c);
Chris@49 1302 access::rw(m).at(in_row2 + aux_row1, c) = m.at(in_row1 + aux_row1, c);
Chris@49 1303 access::rw(m).at(in_row1 + aux_row1, c) = val;
Chris@49 1304 }
Chris@49 1305 }
Chris@49 1306
Chris@49 1307
Chris@49 1308
Chris@49 1309 template<typename eT>
Chris@49 1310 inline
Chris@49 1311 void
Chris@49 1312 SpSubview<eT>::swap_cols(const uword in_col1, const uword in_col2)
Chris@49 1313 {
Chris@49 1314 arma_extra_debug_sigprint();
Chris@49 1315
Chris@49 1316 arma_debug_check((in_col1 >= n_cols) || (in_col2 >= n_cols), "SpSubview::swap_cols(): invalid column index");
Chris@49 1317
Chris@49 1318 const uword lstart_row = aux_row1;
Chris@49 1319 const uword lend_row = aux_row1 + n_rows;
Chris@49 1320
Chris@49 1321 for(uword r = lstart_row; r < lend_row; ++r)
Chris@49 1322 {
Chris@49 1323 eT val = m.at(r, in_col1 + aux_col1);
Chris@49 1324 access::rw(m).at(r, in_col1 + aux_col1) = m.at(r, in_col2 + aux_col1);
Chris@49 1325 access::rw(m).at(r, in_col2 + aux_col1) = val;
Chris@49 1326 }
Chris@49 1327 }
Chris@49 1328
Chris@49 1329
Chris@49 1330
Chris@49 1331 template<typename eT>
Chris@49 1332 inline
Chris@49 1333 typename SpSubview<eT>::iterator
Chris@49 1334 SpSubview<eT>::begin()
Chris@49 1335 {
Chris@49 1336 return iterator(*this);
Chris@49 1337 }
Chris@49 1338
Chris@49 1339
Chris@49 1340
Chris@49 1341 template<typename eT>
Chris@49 1342 inline
Chris@49 1343 typename SpSubview<eT>::const_iterator
Chris@49 1344 SpSubview<eT>::begin() const
Chris@49 1345 {
Chris@49 1346 return const_iterator(*this);
Chris@49 1347 }
Chris@49 1348
Chris@49 1349
Chris@49 1350
Chris@49 1351 template<typename eT>
Chris@49 1352 inline
Chris@49 1353 typename SpSubview<eT>::iterator
Chris@49 1354 SpSubview<eT>::begin_col(const uword col_num)
Chris@49 1355 {
Chris@49 1356 return iterator(*this, 0, col_num);
Chris@49 1357 }
Chris@49 1358
Chris@49 1359
Chris@49 1360 template<typename eT>
Chris@49 1361 inline
Chris@49 1362 typename SpSubview<eT>::const_iterator
Chris@49 1363 SpSubview<eT>::begin_col(const uword col_num) const
Chris@49 1364 {
Chris@49 1365 return const_iterator(*this, 0, col_num);
Chris@49 1366 }
Chris@49 1367
Chris@49 1368
Chris@49 1369
Chris@49 1370 template<typename eT>
Chris@49 1371 inline
Chris@49 1372 typename SpSubview<eT>::row_iterator
Chris@49 1373 SpSubview<eT>::begin_row(const uword row_num)
Chris@49 1374 {
Chris@49 1375 return row_iterator(*this, row_num, 0);
Chris@49 1376 }
Chris@49 1377
Chris@49 1378
Chris@49 1379
Chris@49 1380 template<typename eT>
Chris@49 1381 inline
Chris@49 1382 typename SpSubview<eT>::const_row_iterator
Chris@49 1383 SpSubview<eT>::begin_row(const uword row_num) const
Chris@49 1384 {
Chris@49 1385 return const_row_iterator(*this, row_num, 0);
Chris@49 1386 }
Chris@49 1387
Chris@49 1388
Chris@49 1389
Chris@49 1390 template<typename eT>
Chris@49 1391 inline
Chris@49 1392 typename SpSubview<eT>::iterator
Chris@49 1393 SpSubview<eT>::end()
Chris@49 1394 {
Chris@49 1395 return iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero);
Chris@49 1396 }
Chris@49 1397
Chris@49 1398
Chris@49 1399
Chris@49 1400 template<typename eT>
Chris@49 1401 inline
Chris@49 1402 typename SpSubview<eT>::const_iterator
Chris@49 1403 SpSubview<eT>::end() const
Chris@49 1404 {
Chris@49 1405 return const_iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero);
Chris@49 1406 }
Chris@49 1407
Chris@49 1408
Chris@49 1409
Chris@49 1410 template<typename eT>
Chris@49 1411 inline
Chris@49 1412 typename SpSubview<eT>::row_iterator
Chris@49 1413 SpSubview<eT>::end_row()
Chris@49 1414 {
Chris@49 1415 return row_iterator(*this, n_nonzero);
Chris@49 1416 }
Chris@49 1417
Chris@49 1418
Chris@49 1419
Chris@49 1420 template<typename eT>
Chris@49 1421 inline
Chris@49 1422 typename SpSubview<eT>::const_row_iterator
Chris@49 1423 SpSubview<eT>::end_row() const
Chris@49 1424 {
Chris@49 1425 return const_row_iterator(*this, n_nonzero);
Chris@49 1426 }
Chris@49 1427
Chris@49 1428
Chris@49 1429
Chris@49 1430 template<typename eT>
Chris@49 1431 inline
Chris@49 1432 typename SpSubview<eT>::row_iterator
Chris@49 1433 SpSubview<eT>::end_row(const uword row_num)
Chris@49 1434 {
Chris@49 1435 return row_iterator(*this, row_num + 1, 0);
Chris@49 1436 }
Chris@49 1437
Chris@49 1438
Chris@49 1439
Chris@49 1440 template<typename eT>
Chris@49 1441 inline
Chris@49 1442 typename SpSubview<eT>::const_row_iterator
Chris@49 1443 SpSubview<eT>::end_row(const uword row_num) const
Chris@49 1444 {
Chris@49 1445 return const_row_iterator(*this, row_num + 1, 0);
Chris@49 1446 }
Chris@49 1447
Chris@49 1448
Chris@49 1449
Chris@49 1450 template<typename eT>
Chris@49 1451 inline
Chris@49 1452 arma_hot
Chris@49 1453 arma_warn_unused
Chris@49 1454 eT&
Chris@49 1455 SpSubview<eT>::add_element(const uword in_row, const uword in_col, const eT in_val)
Chris@49 1456 {
Chris@49 1457 arma_extra_debug_sigprint();
Chris@49 1458
Chris@49 1459 // This may not actually add an element.
Chris@49 1460 const uword old_n_nonzero = m.n_nonzero;
Chris@49 1461 eT& retval = access::rw(m).add_element(in_row + aux_row1, in_col + aux_col1, in_val);
Chris@49 1462 // Update n_nonzero (if necessary).
Chris@49 1463 access::rw(n_nonzero) += (m.n_nonzero - old_n_nonzero);
Chris@49 1464
Chris@49 1465 return retval;
Chris@49 1466 }
Chris@49 1467
Chris@49 1468
Chris@49 1469
Chris@49 1470 template<typename eT>
Chris@49 1471 inline
Chris@49 1472 void
Chris@49 1473 SpSubview<eT>::delete_element(const uword in_row, const uword in_col)
Chris@49 1474 {
Chris@49 1475 arma_extra_debug_sigprint();
Chris@49 1476
Chris@49 1477 // This may not actually delete an element.
Chris@49 1478 const uword old_n_nonzero = m.n_nonzero;
Chris@49 1479 access::rw(m).delete_element(in_row + aux_row1, in_col + aux_col1);
Chris@49 1480 access::rw(n_nonzero) -= (old_n_nonzero - m.n_nonzero);
Chris@49 1481 }
Chris@49 1482
Chris@49 1483
Chris@49 1484
Chris@49 1485 /**
Chris@49 1486 * Sparse subview col
Chris@49 1487 *
Chris@49 1488 template<typename eT>
Chris@49 1489 inline
Chris@49 1490 SpSubview_col<eT>::SpSubview_col(const Mat<eT>& in_m, const uword in_col)
Chris@49 1491 {
Chris@49 1492 arma_extra_debug_sigprint();
Chris@49 1493 }
Chris@49 1494
Chris@49 1495 template<typename eT>
Chris@49 1496 inline
Chris@49 1497 SpSubview_col<eT>::SpSubview_col(Mat<eT>& in_m, const uword in_col)
Chris@49 1498 {
Chris@49 1499 arma_extra_debug_sigprint();
Chris@49 1500 }
Chris@49 1501
Chris@49 1502 template<typename eT>
Chris@49 1503 inline
Chris@49 1504 SpSubview_col<eT>::SpSubview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
Chris@49 1505 {
Chris@49 1506 arma_extra_debug_sigprint();
Chris@49 1507 }
Chris@49 1508
Chris@49 1509 template<typename eT>
Chris@49 1510 inline
Chris@49 1511 SpSubview_col<eT>::SpSubview_col(Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
Chris@49 1512 {
Chris@49 1513 arma_extra_debug_sigprint();
Chris@49 1514 }
Chris@49 1515 */
Chris@49 1516
Chris@49 1517 /**
Chris@49 1518 * Sparse subview row
Chris@49 1519 *
Chris@49 1520 template<typename eT>
Chris@49 1521 inline
Chris@49 1522 SpSubview_row<eT>::SpSubview_row(const Mat<eT>& in_m, const uword in_row)
Chris@49 1523 {
Chris@49 1524 arma_extra_debug_sigprint();
Chris@49 1525 }
Chris@49 1526
Chris@49 1527 template<typename eT>
Chris@49 1528 inline
Chris@49 1529 SpSubview_row<eT>::SpSubview_row(Mat<eT>& in_m, const uword in_row)
Chris@49 1530 {
Chris@49 1531 arma_extra_debug_sigprint();
Chris@49 1532 }
Chris@49 1533
Chris@49 1534 template<typename eT>
Chris@49 1535 inline
Chris@49 1536 SpSubview_row<eT>::SpSubview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
Chris@49 1537 {
Chris@49 1538 arma_extra_debug_sigprint();
Chris@49 1539 }
Chris@49 1540
Chris@49 1541 template<typename eT>
Chris@49 1542 inline
Chris@49 1543 SpSubview_row<eT>::SpSubview_row(Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
Chris@49 1544 {
Chris@49 1545 arma_extra_debug_sigprint();
Chris@49 1546 }
Chris@49 1547 */
Chris@49 1548
Chris@49 1549
Chris@49 1550 //! @}