1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17
18
19 //! \addtogroup SpSubview
20 //! @{
21
22
23 template<typename eT>
24 inline
~SpSubview()25 SpSubview<eT>::~SpSubview()
26 {
27 arma_extra_debug_sigprint_this(this);
28 }
29
30
31
32 template<typename eT>
33 inline
SpSubview(const SpMat<eT> & in_m,const uword in_row1,const uword in_col1,const uword in_n_rows,const uword in_n_cols)34 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)
35 : m(in_m)
36 , aux_row1(in_row1)
37 , aux_col1(in_col1)
38 , n_rows(in_n_rows)
39 , n_cols(in_n_cols)
40 , n_elem(in_n_rows * in_n_cols)
41 , n_nonzero(0)
42 {
43 arma_extra_debug_sigprint_this(this);
44
45 m.sync_csc();
46
47 // There must be a O(1) way to do this
48 uword lend = m.col_ptrs[in_col1 + in_n_cols];
49 uword lend_row = in_row1 + in_n_rows;
50 uword count = 0;
51
52 for(uword i = m.col_ptrs[in_col1]; i < lend; ++i)
53 {
54 const uword m_row_indices_i = m.row_indices[i];
55
56 const bool condition = (m_row_indices_i >= in_row1) && (m_row_indices_i < lend_row);
57
58 count += condition ? uword(1) : uword(0);
59 }
60
61 access::rw(n_nonzero) = count;
62 }
63
64
65
66 template<typename eT>
67 inline
SpSubview(const SpSubview<eT> & in)68 SpSubview<eT>::SpSubview(const SpSubview<eT>& in)
69 : m (in.m )
70 , aux_row1 (in.aux_row1 )
71 , aux_col1 (in.aux_col1 )
72 , n_rows (in.n_rows )
73 , n_cols (in.n_cols )
74 , n_elem (in.n_elem )
75 , n_nonzero(in.n_nonzero)
76 {
77 arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in);
78 }
79
80
81
82 template<typename eT>
83 inline
SpSubview(SpSubview<eT> && in)84 SpSubview<eT>::SpSubview(SpSubview<eT>&& in)
85 : m (in.m )
86 , aux_row1 (in.aux_row1 )
87 , aux_col1 (in.aux_col1 )
88 , n_rows (in.n_rows )
89 , n_cols (in.n_cols )
90 , n_elem (in.n_elem )
91 , n_nonzero(in.n_nonzero)
92 {
93 arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in);
94
95 // for paranoia
96
97 access::rw(in.aux_row1 ) = 0;
98 access::rw(in.aux_col1 ) = 0;
99 access::rw(in.n_rows ) = 0;
100 access::rw(in.n_cols ) = 0;
101 access::rw(in.n_elem ) = 0;
102 access::rw(in.n_nonzero) = 0;
103 }
104
105
106
107 template<typename eT>
108 inline
109 const SpSubview<eT>&
operator +=(const eT val)110 SpSubview<eT>::operator+=(const eT val)
111 {
112 arma_extra_debug_sigprint();
113
114 if(val == eT(0)) { return *this; }
115
116 Mat<eT> tmp( (*this).n_rows, (*this).n_cols, arma_nozeros_indicator() );
117
118 tmp.fill(val);
119
120 return (*this).operator=( (*this) + tmp );
121 }
122
123
124
125 template<typename eT>
126 inline
127 const SpSubview<eT>&
operator -=(const eT val)128 SpSubview<eT>::operator-=(const eT val)
129 {
130 arma_extra_debug_sigprint();
131
132 if(val == eT(0)) { return *this; }
133
134 Mat<eT> tmp( (*this).n_rows, (*this).n_cols, arma_nozeros_indicator() );
135
136 tmp.fill(val);
137
138 return (*this).operator=( (*this) - tmp );
139 }
140
141
142
143 template<typename eT>
144 inline
145 const SpSubview<eT>&
operator *=(const eT val)146 SpSubview<eT>::operator*=(const eT val)
147 {
148 arma_extra_debug_sigprint();
149
150 if(val == eT(0)) { (*this).zeros(); return *this; }
151
152 if((n_elem == 0) || (n_nonzero == 0)) { return *this; }
153
154 m.sync_csc();
155 m.invalidate_cache();
156
157 const uword lstart_row = aux_row1;
158 const uword lend_row = aux_row1 + n_rows;
159
160 const uword lstart_col = aux_col1;
161 const uword lend_col = aux_col1 + n_cols;
162
163 const uword* m_row_indices = m.row_indices;
164 eT* m_values = access::rwp(m.values);
165
166 bool has_zero = false;
167
168 for(uword c = lstart_col; c < lend_col; ++c)
169 {
170 const uword r_start = m.col_ptrs[c ];
171 const uword r_end = m.col_ptrs[c + 1];
172
173 for(uword r = r_start; r < r_end; ++r)
174 {
175 const uword m_row_indices_r = m_row_indices[r];
176
177 if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) )
178 {
179 eT& m_values_r = m_values[r];
180
181 m_values_r *= val;
182
183 if(m_values_r == eT(0)) { has_zero = true; }
184 }
185 }
186 }
187
188 if(has_zero)
189 {
190 const uword old_m_n_nonzero = m.n_nonzero;
191
192 access::rw(m).remove_zeros();
193
194 if(m.n_nonzero != old_m_n_nonzero)
195 {
196 access::rw(n_nonzero) = n_nonzero - (old_m_n_nonzero - m.n_nonzero);
197 }
198 }
199
200 return *this;
201 }
202
203
204
205 template<typename eT>
206 inline
207 const SpSubview<eT>&
operator /=(const eT val)208 SpSubview<eT>::operator/=(const eT val)
209 {
210 arma_extra_debug_sigprint();
211
212 arma_debug_check( (val == eT(0)), "element-wise division: division by zero" );
213
214 m.sync_csc();
215 m.invalidate_cache();
216
217 const uword lstart_row = aux_row1;
218 const uword lend_row = aux_row1 + n_rows;
219
220 const uword lstart_col = aux_col1;
221 const uword lend_col = aux_col1 + n_cols;
222
223 const uword* m_row_indices = m.row_indices;
224 eT* m_values = access::rwp(m.values);
225
226 bool has_zero = false;
227
228 for(uword c = lstart_col; c < lend_col; ++c)
229 {
230 const uword r_start = m.col_ptrs[c ];
231 const uword r_end = m.col_ptrs[c + 1];
232
233 for(uword r = r_start; r < r_end; ++r)
234 {
235 const uword m_row_indices_r = m_row_indices[r];
236
237 if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) )
238 {
239 eT& m_values_r = m_values[r];
240
241 m_values_r /= val;
242
243 if(m_values_r == eT(0)) { has_zero = true; }
244 }
245 }
246 }
247
248 if(has_zero)
249 {
250 const uword old_m_n_nonzero = m.n_nonzero;
251
252 access::rw(m).remove_zeros();
253
254 if(m.n_nonzero != old_m_n_nonzero)
255 {
256 access::rw(n_nonzero) = n_nonzero - (old_m_n_nonzero - m.n_nonzero);
257 }
258 }
259
260 return *this;
261 }
262
263
264
265 template<typename eT>
266 template<typename T1>
267 inline
268 const SpSubview<eT>&
operator =(const Base<eT,T1> & in)269 SpSubview<eT>::operator=(const Base<eT, T1>& in)
270 {
271 arma_extra_debug_sigprint();
272
273 if(is_same_type< T1, Gen<Mat<eT>, gen_zeros> >::yes)
274 {
275 const Proxy<T1> P(in.get_ref());
276
277 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "insertion into sparse submatrix");
278
279 (*this).zeros();
280
281 return *this;
282 }
283
284 if(is_same_type< T1, Gen<Mat<eT>, gen_eye> >::yes)
285 {
286 const Proxy<T1> P(in.get_ref());
287
288 arma_debug_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "insertion into sparse submatrix");
289
290 (*this).eye();
291
292 return *this;
293 }
294
295 const quasi_unwrap<T1> U(in.get_ref());
296
297 arma_debug_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "insertion into sparse submatrix");
298
299 spglue_merge::subview_merge(*this, U.M);
300
301 return *this;
302 }
303
304
305
306 template<typename eT>
307 template<typename T1>
308 inline
309 const SpSubview<eT>&
operator +=(const Base<eT,T1> & x)310 SpSubview<eT>::operator+=(const Base<eT, T1>& x)
311 {
312 arma_extra_debug_sigprint();
313
314 return (*this).operator=( (*this) + x.get_ref() );
315 }
316
317
318
319 template<typename eT>
320 template<typename T1>
321 inline
322 const SpSubview<eT>&
operator -=(const Base<eT,T1> & x)323 SpSubview<eT>::operator-=(const Base<eT, T1>& x)
324 {
325 arma_extra_debug_sigprint();
326
327 return (*this).operator=( (*this) - x.get_ref() );
328 }
329
330
331
332 template<typename eT>
333 template<typename T1>
334 inline
335 const SpSubview<eT>&
operator *=(const Base<eT,T1> & x)336 SpSubview<eT>::operator*=(const Base<eT, T1>& x)
337 {
338 arma_extra_debug_sigprint();
339
340 SpMat<eT> tmp(*this);
341
342 tmp *= x.get_ref();
343
344 return (*this).operator=(tmp);
345 }
346
347
348
349 template<typename eT>
350 template<typename T1>
351 inline
352 const SpSubview<eT>&
operator %=(const Base<eT,T1> & x)353 SpSubview<eT>::operator%=(const Base<eT, T1>& x)
354 {
355 arma_extra_debug_sigprint();
356
357 return (*this).operator=( (*this) % x.get_ref() );
358 }
359
360
361
362 template<typename eT>
363 template<typename T1>
364 inline
365 const SpSubview<eT>&
operator /=(const Base<eT,T1> & x)366 SpSubview<eT>::operator/=(const Base<eT, T1>& x)
367 {
368 arma_extra_debug_sigprint();
369
370 return (*this).operator=( (*this) / x.get_ref() );
371 }
372
373
374
375 template<typename eT>
376 inline
377 const SpSubview<eT>&
operator =(const SpSubview<eT> & x)378 SpSubview<eT>::operator=(const SpSubview<eT>& x)
379 {
380 arma_extra_debug_sigprint();
381
382 return (*this).operator_equ_common(x);
383 }
384
385
386
387 template<typename eT>
388 template<typename T1>
389 inline
390 const SpSubview<eT>&
operator =(const SpBase<eT,T1> & x)391 SpSubview<eT>::operator=(const SpBase<eT, T1>& x)
392 {
393 arma_extra_debug_sigprint();
394
395 return (*this).operator_equ_common( x.get_ref() );
396 }
397
398
399
400 template<typename eT>
401 template<typename T1>
402 inline
403 const SpSubview<eT>&
operator_equ_common(const SpBase<eT,T1> & in)404 SpSubview<eT>::operator_equ_common(const SpBase<eT, T1>& in)
405 {
406 arma_extra_debug_sigprint();
407
408 const unwrap_spmat<T1> U(in.get_ref());
409
410 arma_debug_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "insertion into sparse submatrix");
411
412 if(U.is_alias(m))
413 {
414 const SpMat<eT> tmp(U.M);
415
416 spglue_merge::subview_merge(*this, tmp);
417 }
418 else
419 {
420 spglue_merge::subview_merge(*this, U.M);
421 }
422
423 return *this;
424 }
425
426
427
428 template<typename eT>
429 template<typename T1>
430 inline
431 const SpSubview<eT>&
operator +=(const SpBase<eT,T1> & x)432 SpSubview<eT>::operator+=(const SpBase<eT, T1>& x)
433 {
434 arma_extra_debug_sigprint();
435
436 // TODO: implement dedicated machinery
437 return (*this).operator=( (*this) + x.get_ref() );
438 }
439
440
441
442 template<typename eT>
443 template<typename T1>
444 inline
445 const SpSubview<eT>&
operator -=(const SpBase<eT,T1> & x)446 SpSubview<eT>::operator-=(const SpBase<eT, T1>& x)
447 {
448 arma_extra_debug_sigprint();
449
450 // TODO: implement dedicated machinery
451 return (*this).operator=( (*this) - x.get_ref() );
452 }
453
454
455
456 template<typename eT>
457 template<typename T1>
458 inline
459 const SpSubview<eT>&
operator *=(const SpBase<eT,T1> & x)460 SpSubview<eT>::operator*=(const SpBase<eT, T1>& x)
461 {
462 arma_extra_debug_sigprint();
463
464 return (*this).operator=( (*this) * x.get_ref() );
465 }
466
467
468
469 template<typename eT>
470 template<typename T1>
471 inline
472 const SpSubview<eT>&
operator %=(const SpBase<eT,T1> & x)473 SpSubview<eT>::operator%=(const SpBase<eT, T1>& x)
474 {
475 arma_extra_debug_sigprint();
476
477 // TODO: implement dedicated machinery
478 return (*this).operator=( (*this) % x.get_ref() );
479 }
480
481
482
483 template<typename eT>
484 template<typename T1>
485 inline
486 const SpSubview<eT>&
operator /=(const SpBase<eT,T1> & x)487 SpSubview<eT>::operator/=(const SpBase<eT, T1>& x)
488 {
489 arma_extra_debug_sigprint();
490
491 // NOTE: use of this function is not advised; it is implemented only for completeness
492
493 SpProxy<T1> p(x.get_ref());
494
495 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
496
497 if(p.is_alias(m) == false)
498 {
499 for(uword lcol = 0; lcol < n_cols; ++lcol)
500 for(uword lrow = 0; lrow < n_rows; ++lrow)
501 {
502 at(lrow,lcol) /= p.at(lrow,lcol);
503 }
504 }
505 else
506 {
507 const SpMat<eT> tmp(p.Q);
508
509 (*this).operator/=(tmp);
510 }
511
512 return *this;
513 }
514
515
516
517 //! apply a functor to each element
518 template<typename eT>
519 template<typename functor>
520 inline
521 void
for_each(functor F)522 SpSubview<eT>::for_each(functor F)
523 {
524 arma_extra_debug_sigprint();
525
526 m.sync_csc();
527 m.invalidate_cache();
528
529 const uword lstart_row = aux_row1;
530 const uword lend_row = aux_row1 + n_rows;
531
532 const uword lstart_col = aux_col1;
533 const uword lend_col = aux_col1 + n_cols;
534
535 const uword* m_row_indices = m.row_indices;
536 eT* m_values = access::rwp(m.values);
537
538 bool has_zero = false;
539
540 for(uword c = lstart_col; c < lend_col; ++c)
541 {
542 const uword r_start = m.col_ptrs[c ];
543 const uword r_end = m.col_ptrs[c + 1];
544
545 for(uword r = r_start; r < r_end; ++r)
546 {
547 const uword m_row_indices_r = m_row_indices[r];
548
549 if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) )
550 {
551 eT& m_values_r = m_values[r];
552
553 F(m_values_r);
554
555 if(m_values_r == eT(0)) { has_zero = true; }
556 }
557 }
558 }
559
560 if(has_zero)
561 {
562 const uword old_m_n_nonzero = m.n_nonzero;
563
564 access::rw(m).remove_zeros();
565
566 if(m.n_nonzero != old_m_n_nonzero)
567 {
568 access::rw(n_nonzero) = n_nonzero - (old_m_n_nonzero - m.n_nonzero);
569 }
570 }
571 }
572
573
574
575 template<typename eT>
576 template<typename functor>
577 inline
578 void
for_each(functor F) const579 SpSubview<eT>::for_each(functor F) const
580 {
581 arma_extra_debug_sigprint();
582
583 m.sync_csc();
584
585 const uword lstart_row = aux_row1;
586 const uword lend_row = aux_row1 + n_rows;
587
588 const uword lstart_col = aux_col1;
589 const uword lend_col = aux_col1 + n_cols;
590
591 const uword* m_row_indices = m.row_indices;
592
593 for(uword c = lstart_col; c < lend_col; ++c)
594 {
595 const uword r_start = m.col_ptrs[c ];
596 const uword r_end = m.col_ptrs[c + 1];
597
598 for(uword r = r_start; r < r_end; ++r)
599 {
600 const uword m_row_indices_r = m_row_indices[r];
601
602 if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) )
603 {
604 F(m.values[r]);
605 }
606 }
607 }
608 }
609
610
611
612 //! transform each element using a functor
613 template<typename eT>
614 template<typename functor>
615 inline
616 void
transform(functor F)617 SpSubview<eT>::transform(functor F)
618 {
619 arma_extra_debug_sigprint();
620
621 m.sync_csc();
622 m.invalidate_cache();
623
624 const uword lstart_row = aux_row1;
625 const uword lend_row = aux_row1 + n_rows;
626
627 const uword lstart_col = aux_col1;
628 const uword lend_col = aux_col1 + n_cols;
629
630 const uword* m_row_indices = m.row_indices;
631 eT* m_values = access::rwp(m.values);
632
633 bool has_zero = false;
634
635 for(uword c = lstart_col; c < lend_col; ++c)
636 {
637 const uword r_start = m.col_ptrs[c ];
638 const uword r_end = m.col_ptrs[c + 1];
639
640 for(uword r = r_start; r < r_end; ++r)
641 {
642 const uword m_row_indices_r = m_row_indices[r];
643
644 if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) )
645 {
646 eT& m_values_r = m_values[r];
647
648 m_values_r = eT( F(m_values_r) );
649
650 if(m_values_r == eT(0)) { has_zero = true; }
651 }
652 }
653 }
654
655 if(has_zero)
656 {
657 const uword old_m_n_nonzero = m.n_nonzero;
658
659 access::rw(m).remove_zeros();
660
661 if(m.n_nonzero != old_m_n_nonzero)
662 {
663 access::rw(n_nonzero) = n_nonzero - (old_m_n_nonzero - m.n_nonzero);
664 }
665 }
666 }
667
668
669
670 template<typename eT>
671 inline
672 void
replace(const eT old_val,const eT new_val)673 SpSubview<eT>::replace(const eT old_val, const eT new_val)
674 {
675 arma_extra_debug_sigprint();
676
677 if(old_val == eT(0))
678 {
679 if(new_val != eT(0))
680 {
681 Mat<eT> tmp(*this);
682
683 tmp.replace(old_val, new_val);
684
685 (*this).operator=(tmp);
686 }
687
688 return;
689 }
690
691 m.sync_csc();
692 m.invalidate_cache();
693
694 const uword lstart_row = aux_row1;
695 const uword lend_row = aux_row1 + n_rows;
696
697 const uword lstart_col = aux_col1;
698 const uword lend_col = aux_col1 + n_cols;
699
700 const uword* m_row_indices = m.row_indices;
701 eT* m_values = access::rwp(m.values);
702
703 if(arma_isnan(old_val))
704 {
705 for(uword c = lstart_col; c < lend_col; ++c)
706 {
707 const uword r_start = m.col_ptrs[c ];
708 const uword r_end = m.col_ptrs[c + 1];
709
710 for(uword r = r_start; r < r_end; ++r)
711 {
712 const uword m_row_indices_r = m_row_indices[r];
713
714 if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) )
715 {
716 eT& val = m_values[r];
717
718 val = (arma_isnan(val)) ? new_val : val;
719 }
720 }
721 }
722 }
723 else
724 {
725 for(uword c = lstart_col; c < lend_col; ++c)
726 {
727 const uword r_start = m.col_ptrs[c ];
728 const uword r_end = m.col_ptrs[c + 1];
729
730 for(uword r = r_start; r < r_end; ++r)
731 {
732 const uword m_row_indices_r = m_row_indices[r];
733
734 if( (m_row_indices_r >= lstart_row) && (m_row_indices_r < lend_row) )
735 {
736 eT& val = m_values[r];
737
738 val = (val == old_val) ? new_val : val;
739 }
740 }
741 }
742 }
743
744 if(new_val == eT(0)) { access::rw(m).remove_zeros(); }
745 }
746
747
748
749 template<typename eT>
750 inline
751 void
clean(const typename get_pod_type<eT>::result threshold)752 SpSubview<eT>::clean(const typename get_pod_type<eT>::result threshold)
753 {
754 arma_extra_debug_sigprint();
755
756 if((n_elem == 0) || (n_nonzero == 0)) { return; }
757
758 // TODO: replace with a more efficient implementation
759
760 SpMat<eT> tmp(*this);
761
762 tmp.clean(threshold);
763
764 if(is_cx<eT>::yes)
765 {
766 (*this).operator=(tmp);
767 }
768 else
769 if(tmp.n_nonzero != n_nonzero)
770 {
771 (*this).operator=(tmp);
772 }
773 }
774
775
776
777 template<typename eT>
778 inline
779 void
clamp(const eT min_val,const eT max_val)780 SpSubview<eT>::clamp(const eT min_val, const eT max_val)
781 {
782 arma_extra_debug_sigprint();
783
784 if(is_cx<eT>::no)
785 {
786 arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): min_val must be less than max_val" );
787 }
788 else
789 {
790 arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" );
791 arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" );
792 }
793
794 if((n_elem == 0) || (n_nonzero == 0)) { return; }
795
796 // TODO: replace with a more efficient implementation
797
798 SpMat<eT> tmp(*this);
799
800 tmp.clamp(min_val, max_val);
801
802 (*this).operator=(tmp);
803 }
804
805
806
807 template<typename eT>
808 inline
809 void
fill(const eT val)810 SpSubview<eT>::fill(const eT val)
811 {
812 arma_extra_debug_sigprint();
813
814 if(val != eT(0))
815 {
816 Mat<eT> tmp( (*this).n_rows, (*this).n_cols, arma_nozeros_indicator() );
817
818 tmp.fill(val);
819
820 (*this).operator=(tmp);
821 }
822 else
823 {
824 (*this).zeros();
825 }
826 }
827
828
829
830 template<typename eT>
831 inline
832 void
zeros()833 SpSubview<eT>::zeros()
834 {
835 arma_extra_debug_sigprint();
836
837 if((n_elem == 0) || (n_nonzero == 0)) { return; }
838
839 if((m.n_nonzero - n_nonzero) == 0)
840 {
841 access::rw(m).zeros();
842 access::rw(n_nonzero) = 0;
843 return;
844 }
845
846 SpMat<eT> tmp(arma_reserve_indicator(), m.n_rows, m.n_cols, m.n_nonzero - n_nonzero);
847
848 const uword sv_row_start = aux_row1;
849 const uword sv_col_start = aux_col1;
850
851 const uword sv_row_end = aux_row1 + n_rows - 1;
852 const uword sv_col_end = aux_col1 + n_cols - 1;
853
854 typename SpMat<eT>::const_iterator m_it = m.begin();
855 typename SpMat<eT>::const_iterator m_it_end = m.end();
856
857 uword tmp_count = 0;
858
859 for(; m_it != m_it_end; ++m_it)
860 {
861 const uword m_it_row = m_it.row();
862 const uword m_it_col = m_it.col();
863
864 const bool inside_box = ((m_it_row >= sv_row_start) && (m_it_row <= sv_row_end)) && ((m_it_col >= sv_col_start) && (m_it_col <= sv_col_end));
865
866 if(inside_box == false)
867 {
868 access::rw(tmp.values[tmp_count]) = (*m_it);
869 access::rw(tmp.row_indices[tmp_count]) = m_it_row;
870 access::rw(tmp.col_ptrs[m_it_col + 1])++;
871 ++tmp_count;
872 }
873 }
874
875 for(uword i=0; i < tmp.n_cols; ++i)
876 {
877 access::rw(tmp.col_ptrs[i + 1]) += tmp.col_ptrs[i];
878 }
879
880 access::rw(m).steal_mem(tmp);
881
882 access::rw(n_nonzero) = 0;
883 }
884
885
886
887 template<typename eT>
888 inline
889 void
ones()890 SpSubview<eT>::ones()
891 {
892 arma_extra_debug_sigprint();
893
894 (*this).fill(eT(1));
895 }
896
897
898
899 template<typename eT>
900 inline
901 void
eye()902 SpSubview<eT>::eye()
903 {
904 arma_extra_debug_sigprint();
905
906 SpMat<eT> tmp;
907
908 tmp.eye( (*this).n_rows, (*this).n_cols );
909
910 (*this).operator=(tmp);
911 }
912
913
914
915 template<typename eT>
916 inline
917 void
randu()918 SpSubview<eT>::randu()
919 {
920 arma_extra_debug_sigprint();
921
922 Mat<eT> tmp( (*this).n_rows, (*this).n_cols, fill::randu );
923
924 (*this).operator=(tmp);
925 }
926
927
928
929 template<typename eT>
930 inline
931 void
randn()932 SpSubview<eT>::randn()
933 {
934 arma_extra_debug_sigprint();
935
936 Mat<eT> tmp( (*this).n_rows, (*this).n_cols, fill::randn );
937
938 (*this).operator=(tmp);
939 }
940
941
942
943 template<typename eT>
944 arma_hot
945 inline
946 SpSubview_MapMat_val<eT>
operator [](const uword i)947 SpSubview<eT>::operator[](const uword i)
948 {
949 const uword lrow = i % n_rows;
950 const uword lcol = i / n_rows;
951
952 return (*this).at(lrow, lcol);
953 }
954
955
956
957 template<typename eT>
958 arma_hot
959 inline
960 eT
operator [](const uword i) const961 SpSubview<eT>::operator[](const uword i) const
962 {
963 const uword lrow = i % n_rows;
964 const uword lcol = i / n_rows;
965
966 return (*this).at(lrow, lcol);
967 }
968
969
970
971 template<typename eT>
972 arma_hot
973 inline
974 SpSubview_MapMat_val<eT>
operator ()(const uword i)975 SpSubview<eT>::operator()(const uword i)
976 {
977 arma_debug_check_bounds( (i >= n_elem), "SpSubview::operator(): index out of bounds" );
978
979 const uword lrow = i % n_rows;
980 const uword lcol = i / n_rows;
981
982 return (*this).at(lrow, lcol);
983 }
984
985
986
987 template<typename eT>
988 arma_hot
989 inline
990 eT
operator ()(const uword i) const991 SpSubview<eT>::operator()(const uword i) const
992 {
993 arma_debug_check_bounds( (i >= n_elem), "SpSubview::operator(): index out of bounds" );
994
995 const uword lrow = i % n_rows;
996 const uword lcol = i / n_rows;
997
998 return (*this).at(lrow, lcol);
999 }
1000
1001
1002
1003 template<typename eT>
1004 arma_hot
1005 inline
1006 SpSubview_MapMat_val<eT>
operator ()(const uword in_row,const uword in_col)1007 SpSubview<eT>::operator()(const uword in_row, const uword in_col)
1008 {
1009 arma_debug_check_bounds( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds" );
1010
1011 return (*this).at(in_row, in_col);
1012 }
1013
1014
1015
1016 template<typename eT>
1017 arma_hot
1018 inline
1019 eT
operator ()(const uword in_row,const uword in_col) const1020 SpSubview<eT>::operator()(const uword in_row, const uword in_col) const
1021 {
1022 arma_debug_check_bounds( (in_row >= n_rows) || (in_col >= n_cols), "SpSubview::operator(): index out of bounds" );
1023
1024 return (*this).at(in_row, in_col);
1025 }
1026
1027
1028
1029 template<typename eT>
1030 arma_hot
1031 inline
1032 SpSubview_MapMat_val<eT>
at(const uword i)1033 SpSubview<eT>::at(const uword i)
1034 {
1035 const uword lrow = i % n_rows;
1036 const uword lcol = i / n_cols;
1037
1038 return (*this).at(lrow, lcol);
1039 }
1040
1041
1042
1043 template<typename eT>
1044 arma_hot
1045 inline
1046 eT
at(const uword i) const1047 SpSubview<eT>::at(const uword i) const
1048 {
1049 const uword lrow = i % n_rows;
1050 const uword lcol = i / n_cols;
1051
1052 return (*this).at(lrow, lcol);
1053 }
1054
1055
1056
1057 template<typename eT>
1058 arma_hot
1059 inline
1060 SpSubview_MapMat_val<eT>
at(const uword in_row,const uword in_col)1061 SpSubview<eT>::at(const uword in_row, const uword in_col)
1062 {
1063 return SpSubview_MapMat_val<eT>((*this), m.cache, aux_row1 + in_row, aux_col1 + in_col);
1064 }
1065
1066
1067
1068 template<typename eT>
1069 arma_hot
1070 inline
1071 eT
at(const uword in_row,const uword in_col) const1072 SpSubview<eT>::at(const uword in_row, const uword in_col) const
1073 {
1074 return m.at(aux_row1 + in_row, aux_col1 + in_col);
1075 }
1076
1077
1078
1079 template<typename eT>
1080 inline
1081 bool
check_overlap(const SpSubview<eT> & x) const1082 SpSubview<eT>::check_overlap(const SpSubview<eT>& x) const
1083 {
1084 const SpSubview<eT>& t = *this;
1085
1086 if(&t.m != &x.m)
1087 {
1088 return false;
1089 }
1090 else
1091 {
1092 if( (t.n_elem == 0) || (x.n_elem == 0) )
1093 {
1094 return false;
1095 }
1096 else
1097 {
1098 const uword t_row_start = t.aux_row1;
1099 const uword t_row_end_p1 = t_row_start + t.n_rows;
1100
1101 const uword t_col_start = t.aux_col1;
1102 const uword t_col_end_p1 = t_col_start + t.n_cols;
1103
1104 const uword x_row_start = x.aux_row1;
1105 const uword x_row_end_p1 = x_row_start + x.n_rows;
1106
1107 const uword x_col_start = x.aux_col1;
1108 const uword x_col_end_p1 = x_col_start + x.n_cols;
1109
1110 const bool outside_rows = ( (x_row_start >= t_row_end_p1) || (t_row_start >= x_row_end_p1) );
1111 const bool outside_cols = ( (x_col_start >= t_col_end_p1) || (t_col_start >= x_col_end_p1) );
1112
1113 return ( (outside_rows == false) && (outside_cols == false) );
1114 }
1115 }
1116 }
1117
1118
1119
1120 template<typename eT>
1121 inline
1122 bool
is_vec() const1123 SpSubview<eT>::is_vec() const
1124 {
1125 return ( (n_rows == 1) || (n_cols == 1) );
1126 }
1127
1128
1129
1130 template<typename eT>
1131 inline
1132 SpSubview_row<eT>
row(const uword row_num)1133 SpSubview<eT>::row(const uword row_num)
1134 {
1135 arma_extra_debug_sigprint();
1136
1137 arma_debug_check_bounds(row_num >= n_rows, "SpSubview::row(): out of bounds");
1138
1139 return SpSubview_row<eT>(const_cast< SpMat<eT>& >(m), row_num + aux_row1, aux_col1, n_cols);
1140 }
1141
1142
1143
1144 template<typename eT>
1145 inline
1146 const SpSubview_row<eT>
row(const uword row_num) const1147 SpSubview<eT>::row(const uword row_num) const
1148 {
1149 arma_extra_debug_sigprint();
1150
1151 arma_debug_check_bounds(row_num >= n_rows, "SpSubview::row(): out of bounds");
1152
1153 return SpSubview_row<eT>(m, row_num + aux_row1, aux_col1, n_cols);
1154 }
1155
1156
1157
1158 template<typename eT>
1159 inline
1160 SpSubview_col<eT>
col(const uword col_num)1161 SpSubview<eT>::col(const uword col_num)
1162 {
1163 arma_extra_debug_sigprint();
1164
1165 arma_debug_check_bounds(col_num >= n_cols, "SpSubview::col(): out of bounds");
1166
1167 return SpSubview_col<eT>(const_cast< SpMat<eT>& >(m), col_num + aux_col1, aux_row1, n_rows);
1168 }
1169
1170
1171
1172 template<typename eT>
1173 inline
1174 const SpSubview_col<eT>
col(const uword col_num) const1175 SpSubview<eT>::col(const uword col_num) const
1176 {
1177 arma_extra_debug_sigprint();
1178
1179 arma_debug_check_bounds(col_num >= n_cols, "SpSubview::col(): out of bounds");
1180
1181 return SpSubview_col<eT>(m, col_num + aux_col1, aux_row1, n_rows);
1182 }
1183
1184
1185
1186 template<typename eT>
1187 inline
1188 SpSubview<eT>
rows(const uword in_row1,const uword in_row2)1189 SpSubview<eT>::rows(const uword in_row1, const uword in_row2)
1190 {
1191 arma_extra_debug_sigprint();
1192
1193 arma_debug_check_bounds
1194 (
1195 (in_row1 > in_row2) || (in_row2 >= n_rows),
1196 "SpSubview::rows(): indices out of bounds or incorrectly used"
1197 );
1198
1199 return submat(in_row1, 0, in_row2, n_cols - 1);
1200 }
1201
1202
1203
1204 template<typename eT>
1205 inline
1206 const SpSubview<eT>
rows(const uword in_row1,const uword in_row2) const1207 SpSubview<eT>::rows(const uword in_row1, const uword in_row2) const
1208 {
1209 arma_extra_debug_sigprint();
1210
1211 arma_debug_check_bounds
1212 (
1213 (in_row1 > in_row2) || (in_row2 >= n_rows),
1214 "SpSubview::rows(): indices out of bounds or incorrectly used"
1215 );
1216
1217 return submat(in_row1, 0, in_row2, n_cols - 1);
1218 }
1219
1220
1221
1222 template<typename eT>
1223 inline
1224 SpSubview<eT>
cols(const uword in_col1,const uword in_col2)1225 SpSubview<eT>::cols(const uword in_col1, const uword in_col2)
1226 {
1227 arma_extra_debug_sigprint();
1228
1229 arma_debug_check_bounds
1230 (
1231 (in_col1 > in_col2) || (in_col2 >= n_cols),
1232 "SpSubview::cols(): indices out of bounds or incorrectly used"
1233 );
1234
1235 return submat(0, in_col1, n_rows - 1, in_col2);
1236 }
1237
1238
1239
1240 template<typename eT>
1241 inline
1242 const SpSubview<eT>
cols(const uword in_col1,const uword in_col2) const1243 SpSubview<eT>::cols(const uword in_col1, const uword in_col2) const
1244 {
1245 arma_extra_debug_sigprint();
1246
1247 arma_debug_check_bounds
1248 (
1249 (in_col1 > in_col2) || (in_col2 >= n_cols),
1250 "SpSubview::cols(): indices out of bounds or incorrectly used"
1251 );
1252
1253 return submat(0, in_col1, n_rows - 1, in_col2);
1254 }
1255
1256
1257
1258 template<typename eT>
1259 inline
1260 SpSubview<eT>
submat(const uword in_row1,const uword in_col1,const uword in_row2,const uword in_col2)1261 SpSubview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
1262 {
1263 arma_extra_debug_sigprint();
1264
1265 arma_debug_check_bounds
1266 (
1267 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
1268 "SpSubview::submat(): indices out of bounds or incorrectly used"
1269 );
1270
1271 return access::rw(m).submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1);
1272 }
1273
1274
1275
1276 template<typename eT>
1277 inline
1278 const SpSubview<eT>
submat(const uword in_row1,const uword in_col1,const uword in_row2,const uword in_col2) const1279 SpSubview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
1280 {
1281 arma_extra_debug_sigprint();
1282
1283 arma_debug_check_bounds
1284 (
1285 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
1286 "SpSubview::submat(): indices out of bounds or incorrectly used"
1287 );
1288
1289 return m.submat(in_row1 + aux_row1, in_col1 + aux_col1, in_row2 + aux_row1, in_col2 + aux_col1);
1290 }
1291
1292
1293
1294 template<typename eT>
1295 inline
1296 SpSubview<eT>
submat(const span & row_span,const span & col_span)1297 SpSubview<eT>::submat(const span& row_span, const span& col_span)
1298 {
1299 arma_extra_debug_sigprint();
1300
1301 const bool row_all = row_span.whole;
1302 const bool col_all = row_span.whole;
1303
1304 const uword in_row1 = row_all ? 0 : row_span.a;
1305 const uword in_row2 = row_all ? n_rows : row_span.b;
1306
1307 const uword in_col1 = col_all ? 0 : col_span.a;
1308 const uword in_col2 = col_all ? n_cols : col_span.b;
1309
1310 arma_debug_check_bounds
1311 (
1312 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows)))
1313 ||
1314 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))),
1315 "SpSubview::submat(): indices out of bounds or incorrectly used"
1316 );
1317
1318 return submat(in_row1, in_col1, in_row2, in_col2);
1319 }
1320
1321
1322
1323 template<typename eT>
1324 inline
1325 const SpSubview<eT>
submat(const span & row_span,const span & col_span) const1326 SpSubview<eT>::submat(const span& row_span, const span& col_span) const
1327 {
1328 arma_extra_debug_sigprint();
1329
1330 const bool row_all = row_span.whole;
1331 const bool col_all = row_span.whole;
1332
1333 const uword in_row1 = row_all ? 0 : row_span.a;
1334 const uword in_row2 = row_all ? n_rows - 1 : row_span.b;
1335
1336 const uword in_col1 = col_all ? 0 : col_span.a;
1337 const uword in_col2 = col_all ? n_cols - 1 : col_span.b;
1338
1339 arma_debug_check_bounds
1340 (
1341 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= n_rows)))
1342 ||
1343 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= n_cols))),
1344 "SpSubview::submat(): indices out of bounds or incorrectly used"
1345 );
1346
1347 return submat(in_row1, in_col1, in_row2, in_col2);
1348 }
1349
1350
1351
1352 template<typename eT>
1353 inline
1354 SpSubview<eT>
operator ()(const uword row_num,const span & col_span)1355 SpSubview<eT>::operator()(const uword row_num, const span& col_span)
1356 {
1357 arma_extra_debug_sigprint();
1358
1359 return submat(span(row_num, row_num), col_span);
1360 }
1361
1362
1363
1364 template<typename eT>
1365 inline
1366 const SpSubview<eT>
operator ()(const uword row_num,const span & col_span) const1367 SpSubview<eT>::operator()(const uword row_num, const span& col_span) const
1368 {
1369 arma_extra_debug_sigprint();
1370
1371 return submat(span(row_num, row_num), col_span);
1372 }
1373
1374
1375
1376 template<typename eT>
1377 inline
1378 SpSubview<eT>
operator ()(const span & row_span,const uword col_num)1379 SpSubview<eT>::operator()(const span& row_span, const uword col_num)
1380 {
1381 arma_extra_debug_sigprint();
1382
1383 return submat(row_span, span(col_num, col_num));
1384 }
1385
1386
1387
1388 template<typename eT>
1389 inline
1390 const SpSubview<eT>
operator ()(const span & row_span,const uword col_num) const1391 SpSubview<eT>::operator()(const span& row_span, const uword col_num) const
1392 {
1393 arma_extra_debug_sigprint();
1394
1395 return submat(row_span, span(col_num, col_num));
1396 }
1397
1398
1399
1400 template<typename eT>
1401 inline
1402 SpSubview<eT>
operator ()(const span & row_span,const span & col_span)1403 SpSubview<eT>::operator()(const span& row_span, const span& col_span)
1404 {
1405 arma_extra_debug_sigprint();
1406
1407 return submat(row_span, col_span);
1408 }
1409
1410
1411
1412 template<typename eT>
1413 inline
1414 const SpSubview<eT>
operator ()(const span & row_span,const span & col_span) const1415 SpSubview<eT>::operator()(const span& row_span, const span& col_span) const
1416 {
1417 arma_extra_debug_sigprint();
1418
1419 return submat(row_span, col_span);
1420 }
1421
1422
1423
1424 template<typename eT>
1425 inline
1426 void
swap_rows(const uword in_row1,const uword in_row2)1427 SpSubview<eT>::swap_rows(const uword in_row1, const uword in_row2)
1428 {
1429 arma_extra_debug_sigprint();
1430
1431 arma_debug_check((in_row1 >= n_rows) || (in_row2 >= n_rows), "SpSubview::swap_rows(): invalid row index");
1432
1433 const uword lstart_col = aux_col1;
1434 const uword lend_col = aux_col1 + n_cols;
1435
1436 for(uword c = lstart_col; c < lend_col; ++c)
1437 {
1438 const eT val = access::rw(m).at(in_row1 + aux_row1, c);
1439 access::rw(m).at(in_row2 + aux_row1, c) = eT( access::rw(m).at(in_row1 + aux_row1, c) );
1440 access::rw(m).at(in_row1 + aux_row1, c) = val;
1441 }
1442 }
1443
1444
1445
1446 template<typename eT>
1447 inline
1448 void
swap_cols(const uword in_col1,const uword in_col2)1449 SpSubview<eT>::swap_cols(const uword in_col1, const uword in_col2)
1450 {
1451 arma_extra_debug_sigprint();
1452
1453 arma_debug_check((in_col1 >= n_cols) || (in_col2 >= n_cols), "SpSubview::swap_cols(): invalid column index");
1454
1455 const uword lstart_row = aux_row1;
1456 const uword lend_row = aux_row1 + n_rows;
1457
1458 for(uword r = lstart_row; r < lend_row; ++r)
1459 {
1460 const eT val = access::rw(m).at(r, in_col1 + aux_col1);
1461 access::rw(m).at(r, in_col1 + aux_col1) = eT( access::rw(m).at(r, in_col2 + aux_col1) );
1462 access::rw(m).at(r, in_col2 + aux_col1) = val;
1463 }
1464 }
1465
1466
1467
1468 template<typename eT>
1469 inline
1470 typename SpSubview<eT>::iterator
begin()1471 SpSubview<eT>::begin()
1472 {
1473 return iterator(*this);
1474 }
1475
1476
1477
1478 template<typename eT>
1479 inline
1480 typename SpSubview<eT>::const_iterator
begin() const1481 SpSubview<eT>::begin() const
1482 {
1483 m.sync_csc();
1484
1485 return const_iterator(*this);
1486 }
1487
1488
1489
1490 template<typename eT>
1491 inline
1492 typename SpSubview<eT>::const_iterator
cbegin() const1493 SpSubview<eT>::cbegin() const
1494 {
1495 m.sync_csc();
1496
1497 return const_iterator(*this);
1498 }
1499
1500
1501
1502 template<typename eT>
1503 inline
1504 typename SpSubview<eT>::iterator
begin_col(const uword col_num)1505 SpSubview<eT>::begin_col(const uword col_num)
1506 {
1507 m.sync_csc();
1508
1509 return iterator(*this, 0, col_num);
1510 }
1511
1512
1513 template<typename eT>
1514 inline
1515 typename SpSubview<eT>::const_iterator
begin_col(const uword col_num) const1516 SpSubview<eT>::begin_col(const uword col_num) const
1517 {
1518 m.sync_csc();
1519
1520 return const_iterator(*this, 0, col_num);
1521 }
1522
1523
1524
1525 template<typename eT>
1526 inline
1527 typename SpSubview<eT>::row_iterator
begin_row(const uword row_num)1528 SpSubview<eT>::begin_row(const uword row_num)
1529 {
1530 m.sync_csc();
1531
1532 return row_iterator(*this, row_num, 0);
1533 }
1534
1535
1536
1537 template<typename eT>
1538 inline
1539 typename SpSubview<eT>::const_row_iterator
begin_row(const uword row_num) const1540 SpSubview<eT>::begin_row(const uword row_num) const
1541 {
1542 m.sync_csc();
1543
1544 return const_row_iterator(*this, row_num, 0);
1545 }
1546
1547
1548
1549 template<typename eT>
1550 inline
1551 typename SpSubview<eT>::iterator
end()1552 SpSubview<eT>::end()
1553 {
1554 m.sync_csc();
1555
1556 return iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero);
1557 }
1558
1559
1560
1561 template<typename eT>
1562 inline
1563 typename SpSubview<eT>::const_iterator
end() const1564 SpSubview<eT>::end() const
1565 {
1566 m.sync_csc();
1567
1568 return const_iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero);
1569 }
1570
1571
1572
1573 template<typename eT>
1574 inline
1575 typename SpSubview<eT>::const_iterator
cend() const1576 SpSubview<eT>::cend() const
1577 {
1578 m.sync_csc();
1579
1580 return const_iterator(*this, 0, n_cols, n_nonzero, m.n_nonzero - n_nonzero);
1581 }
1582
1583
1584
1585 template<typename eT>
1586 inline
1587 typename SpSubview<eT>::row_iterator
end_row()1588 SpSubview<eT>::end_row()
1589 {
1590 m.sync_csc();
1591
1592 return row_iterator(*this, n_nonzero);
1593 }
1594
1595
1596
1597 template<typename eT>
1598 inline
1599 typename SpSubview<eT>::const_row_iterator
end_row() const1600 SpSubview<eT>::end_row() const
1601 {
1602 m.sync_csc();
1603
1604 return const_row_iterator(*this, n_nonzero);
1605 }
1606
1607
1608
1609 template<typename eT>
1610 inline
1611 typename SpSubview<eT>::row_iterator
end_row(const uword row_num)1612 SpSubview<eT>::end_row(const uword row_num)
1613 {
1614 m.sync_csc();
1615
1616 return row_iterator(*this, row_num + 1, 0);
1617 }
1618
1619
1620
1621 template<typename eT>
1622 inline
1623 typename SpSubview<eT>::const_row_iterator
end_row(const uword row_num) const1624 SpSubview<eT>::end_row(const uword row_num) const
1625 {
1626 m.sync_csc();
1627
1628 return const_row_iterator(*this, row_num + 1, 0);
1629 }
1630
1631
1632
1633 template<typename eT>
1634 arma_inline
1635 bool
is_alias(const SpMat<eT> & X) const1636 SpSubview<eT>::is_alias(const SpMat<eT>& X) const
1637 {
1638 return m.is_alias(X);
1639 }
1640
1641
1642
1643 template<typename eT>
1644 inline
1645 arma_warn_unused
1646 eT&
insert_element(const uword in_row,const uword in_col,const eT in_val)1647 SpSubview<eT>::insert_element(const uword in_row, const uword in_col, const eT in_val)
1648 {
1649 arma_extra_debug_sigprint();
1650
1651 // This may not actually insert an element.
1652 const uword old_n_nonzero = m.n_nonzero;
1653 eT& retval = access::rw(m).insert_element(in_row + aux_row1, in_col + aux_col1, in_val);
1654 // Update n_nonzero (if necessary).
1655 access::rw(n_nonzero) += (m.n_nonzero - old_n_nonzero);
1656
1657 return retval;
1658 }
1659
1660
1661
1662 template<typename eT>
1663 inline
1664 void
delete_element(const uword in_row,const uword in_col)1665 SpSubview<eT>::delete_element(const uword in_row, const uword in_col)
1666 {
1667 arma_extra_debug_sigprint();
1668
1669 // This may not actually delete an element.
1670 const uword old_n_nonzero = m.n_nonzero;
1671 access::rw(m).delete_element(in_row + aux_row1, in_col + aux_col1);
1672 access::rw(n_nonzero) -= (old_n_nonzero - m.n_nonzero);
1673 }
1674
1675
1676
1677 template<typename eT>
1678 inline
1679 void
invalidate_cache() const1680 SpSubview<eT>::invalidate_cache() const
1681 {
1682 arma_extra_debug_sigprint();
1683
1684 m.invalidate_cache();
1685 }
1686
1687
1688
1689 //
1690 //
1691 //
1692
1693
1694
1695 template<typename eT>
1696 inline
SpSubview_col(const SpMat<eT> & in_m,const uword in_col)1697 SpSubview_col<eT>::SpSubview_col(const SpMat<eT>& in_m, const uword in_col)
1698 : SpSubview<eT>(in_m, 0, in_col, in_m.n_rows, 1)
1699 {
1700 arma_extra_debug_sigprint();
1701 }
1702
1703
1704
1705 template<typename eT>
1706 inline
SpSubview_col(const SpMat<eT> & in_m,const uword in_col,const uword in_row1,const uword in_n_rows)1707 SpSubview_col<eT>::SpSubview_col(const SpMat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
1708 : SpSubview<eT>(in_m, in_row1, in_col, in_n_rows, 1)
1709 {
1710 arma_extra_debug_sigprint();
1711 }
1712
1713
1714
1715 template<typename eT>
1716 inline
1717 void
operator =(const SpSubview<eT> & x)1718 SpSubview_col<eT>::operator=(const SpSubview<eT>& x)
1719 {
1720 arma_extra_debug_sigprint();
1721
1722 SpSubview<eT>::operator=(x);
1723 }
1724
1725
1726
1727 template<typename eT>
1728 inline
1729 void
operator =(const SpSubview_col<eT> & x)1730 SpSubview_col<eT>::operator=(const SpSubview_col<eT>& x)
1731 {
1732 arma_extra_debug_sigprint();
1733
1734 SpSubview<eT>::operator=(x); // interprets 'SpSubview_col' as 'SpSubview'
1735 }
1736
1737
1738
1739 template<typename eT>
1740 template<typename T1>
1741 inline
1742 void
operator =(const SpBase<eT,T1> & x)1743 SpSubview_col<eT>::operator=(const SpBase<eT,T1>& x)
1744 {
1745 arma_extra_debug_sigprint();
1746
1747 SpSubview<eT>::operator=(x);
1748 }
1749
1750
1751
1752 template<typename eT>
1753 template<typename T1>
1754 inline
1755 void
operator =(const Base<eT,T1> & x)1756 SpSubview_col<eT>::operator=(const Base<eT,T1>& x)
1757 {
1758 arma_extra_debug_sigprint();
1759
1760 SpSubview<eT>::operator=(x);
1761 }
1762
1763
1764
1765 template<typename eT>
1766 inline
1767 arma_warn_unused
1768 const SpOp<SpSubview_col<eT>,spop_htrans>
t() const1769 SpSubview_col<eT>::t() const
1770 {
1771 return SpOp<SpSubview_col<eT>,spop_htrans>(*this);
1772 }
1773
1774
1775
1776 template<typename eT>
1777 inline
1778 arma_warn_unused
1779 const SpOp<SpSubview_col<eT>,spop_htrans>
ht() const1780 SpSubview_col<eT>::ht() const
1781 {
1782 return SpOp<SpSubview_col<eT>,spop_htrans>(*this);
1783 }
1784
1785
1786
1787 template<typename eT>
1788 inline
1789 arma_warn_unused
1790 const SpOp<SpSubview_col<eT>,spop_strans>
st() const1791 SpSubview_col<eT>::st() const
1792 {
1793 return SpOp<SpSubview_col<eT>,spop_strans>(*this);
1794 }
1795
1796
1797
1798 //
1799 //
1800 //
1801
1802
1803
1804 template<typename eT>
1805 inline
SpSubview_row(const SpMat<eT> & in_m,const uword in_row)1806 SpSubview_row<eT>::SpSubview_row(const SpMat<eT>& in_m, const uword in_row)
1807 : SpSubview<eT>(in_m, in_row, 0, 1, in_m.n_cols)
1808 {
1809 arma_extra_debug_sigprint();
1810 }
1811
1812
1813
1814 template<typename eT>
1815 inline
SpSubview_row(const SpMat<eT> & in_m,const uword in_row,const uword in_col1,const uword in_n_cols)1816 SpSubview_row<eT>::SpSubview_row(const SpMat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
1817 : SpSubview<eT>(in_m, in_row, in_col1, 1, in_n_cols)
1818 {
1819 arma_extra_debug_sigprint();
1820 }
1821
1822
1823
1824 template<typename eT>
1825 inline
1826 void
operator =(const SpSubview<eT> & x)1827 SpSubview_row<eT>::operator=(const SpSubview<eT>& x)
1828 {
1829 arma_extra_debug_sigprint();
1830
1831 SpSubview<eT>::operator=(x);
1832 }
1833
1834
1835
1836 template<typename eT>
1837 inline
1838 void
operator =(const SpSubview_row<eT> & x)1839 SpSubview_row<eT>::operator=(const SpSubview_row<eT>& x)
1840 {
1841 arma_extra_debug_sigprint();
1842
1843 SpSubview<eT>::operator=(x); // interprets 'SpSubview_row' as 'SpSubview'
1844 }
1845
1846
1847
1848 template<typename eT>
1849 template<typename T1>
1850 inline
1851 void
operator =(const SpBase<eT,T1> & x)1852 SpSubview_row<eT>::operator=(const SpBase<eT,T1>& x)
1853 {
1854 arma_extra_debug_sigprint();
1855
1856 SpSubview<eT>::operator=(x);
1857 }
1858
1859
1860
1861 template<typename eT>
1862 template<typename T1>
1863 inline
1864 void
operator =(const Base<eT,T1> & x)1865 SpSubview_row<eT>::operator=(const Base<eT,T1>& x)
1866 {
1867 arma_extra_debug_sigprint();
1868
1869 SpSubview<eT>::operator=(x);
1870 }
1871
1872
1873
1874 template<typename eT>
1875 inline
1876 arma_warn_unused
1877 const SpOp<SpSubview_row<eT>,spop_htrans>
t() const1878 SpSubview_row<eT>::t() const
1879 {
1880 return SpOp<SpSubview_row<eT>,spop_htrans>(*this);
1881 }
1882
1883
1884
1885 template<typename eT>
1886 inline
1887 arma_warn_unused
1888 const SpOp<SpSubview_row<eT>,spop_htrans>
ht() const1889 SpSubview_row<eT>::ht() const
1890 {
1891 return SpOp<SpSubview_row<eT>,spop_htrans>(*this);
1892 }
1893
1894
1895
1896 template<typename eT>
1897 inline
1898 arma_warn_unused
1899 const SpOp<SpSubview_row<eT>,spop_strans>
st() const1900 SpSubview_row<eT>::st() const
1901 {
1902 return SpOp<SpSubview_row<eT>,spop_strans>(*this);
1903 }
1904
1905
1906
1907 //! @}
1908