"Fossies" - the Fresh Open Source Software Archive 
Member "armadillo-9.800.3/include/armadillo_bits/MapMat_meat.hpp" (16 Jun 2016, 34555 Bytes) of package /linux/misc/armadillo-9.800.3.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "MapMat_meat.hpp" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
9.600.4_vs_9.600.5.
1 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
2 // Copyright 2008-2016 National ICT Australia (NICTA)
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ------------------------------------------------------------------------
15
16
17 //! \addtogroup MapMat
18 //! @{
19
20
21
22 template<typename eT>
23 inline
24 MapMat<eT>::~MapMat()
25 {
26 arma_extra_debug_sigprint_this(this);
27
28 if(map_ptr) { (*map_ptr).clear(); delete map_ptr; }
29
30 // try to expose buggy user code that accesses deleted objects
31 if(arma_config::debug) { map_ptr = NULL; }
32
33 arma_type_check(( is_supported_elem_type<eT>::value == false ));
34 }
35
36
37
38 template<typename eT>
39 inline
40 MapMat<eT>::MapMat()
41 : n_rows (0)
42 , n_cols (0)
43 , n_elem (0)
44 , map_ptr(NULL)
45 {
46 arma_extra_debug_sigprint_this(this);
47
48 init_cold();
49 }
50
51
52
53 template<typename eT>
54 inline
55 MapMat<eT>::MapMat(const uword in_n_rows, const uword in_n_cols)
56 : n_rows (in_n_rows)
57 , n_cols (in_n_cols)
58 , n_elem (in_n_rows * in_n_cols)
59 , map_ptr(NULL)
60 {
61 arma_extra_debug_sigprint_this(this);
62
63 init_cold();
64 }
65
66
67
68 template<typename eT>
69 inline
70 MapMat<eT>::MapMat(const SizeMat& s)
71 : n_rows (s.n_rows)
72 , n_cols (s.n_cols)
73 , n_elem (s.n_rows * s.n_cols)
74 , map_ptr(NULL)
75 {
76 arma_extra_debug_sigprint_this(this);
77
78 init_cold();
79 }
80
81
82
83 template<typename eT>
84 inline
85 MapMat<eT>::MapMat(const MapMat<eT>& x)
86 : n_rows (0)
87 , n_cols (0)
88 , n_elem (0)
89 , map_ptr(NULL)
90 {
91 arma_extra_debug_sigprint_this(this);
92
93 init_cold();
94
95 (*this).operator=(x);
96 }
97
98
99
100 template<typename eT>
101 inline
102 void
103 MapMat<eT>::operator=(const MapMat<eT>& x)
104 {
105 arma_extra_debug_sigprint();
106
107 if(this == &x) { return; }
108
109 access::rw(n_rows) = x.n_rows;
110 access::rw(n_cols) = x.n_cols;
111 access::rw(n_elem) = x.n_elem;
112
113 (*map_ptr) = *(x.map_ptr);
114 }
115
116
117
118 template<typename eT>
119 inline
120 MapMat<eT>::MapMat(const SpMat<eT>& x)
121 : n_rows (0)
122 , n_cols (0)
123 , n_elem (0)
124 , map_ptr(NULL)
125 {
126 arma_extra_debug_sigprint_this(this);
127
128 init_cold();
129
130 (*this).operator=(x);
131 }
132
133
134
135 template<typename eT>
136 inline
137 void
138 MapMat<eT>::operator=(const SpMat<eT>& x)
139 {
140 arma_extra_debug_sigprint();
141
142 const uword x_n_rows = x.n_rows;
143 const uword x_n_cols = x.n_cols;
144
145 (*this).zeros(x_n_rows, x_n_cols);
146
147 if(x.n_nonzero == 0) { return; }
148
149 const eT* x_values = x.values;
150 const uword* x_row_indices = x.row_indices;
151 const uword* x_col_ptrs = x.col_ptrs;
152
153 map_type& map_ref = (*map_ptr);
154
155 for(uword col = 0; col < x_n_cols; ++col)
156 {
157 const uword start = x_col_ptrs[col ];
158 const uword end = x_col_ptrs[col + 1];
159
160 for(uword i = start; i < end; ++i)
161 {
162 const uword row = x_row_indices[i];
163 const eT val = x_values[i];
164
165 const uword index = (x_n_rows * col) + row;
166
167 #if defined(ARMA_USE_CXX11)
168 map_ref.emplace_hint(map_ref.cend(), index, val);
169 #else
170 map_ref.operator[](index) = val;
171 #endif
172 }
173 }
174 }
175
176
177
178 #if defined(ARMA_USE_CXX11)
179
180 template<typename eT>
181 inline
182 MapMat<eT>::MapMat(MapMat<eT>&& x)
183 : n_rows (x.n_rows )
184 , n_cols (x.n_cols )
185 , n_elem (x.n_elem )
186 , map_ptr(x.map_ptr)
187 {
188 arma_extra_debug_sigprint_this(this);
189
190 access::rw(x.n_rows) = 0;
191 access::rw(x.n_cols) = 0;
192 access::rw(x.n_elem) = 0;
193 access::rw(x.map_ptr) = NULL;
194 }
195
196
197
198 template<typename eT>
199 inline
200 void
201 MapMat<eT>::operator=(MapMat<eT>&& x)
202 {
203 arma_extra_debug_sigprint();
204
205 reset();
206
207 if(map_ptr) { delete map_ptr; }
208
209 access::rw(n_rows) = x.n_rows;
210 access::rw(n_cols) = x.n_cols;
211 access::rw(n_elem) = x.n_elem;
212 access::rw(map_ptr) = x.map_ptr;
213
214 access::rw(x.n_rows) = 0;
215 access::rw(x.n_cols) = 0;
216 access::rw(x.n_elem) = 0;
217 access::rw(x.map_ptr) = NULL;
218 }
219
220 #endif
221
222
223
224 template<typename eT>
225 inline
226 void
227 MapMat<eT>::reset()
228 {
229 arma_extra_debug_sigprint();
230
231 access::rw(n_rows) = 0;
232 access::rw(n_cols) = 0;
233 access::rw(n_elem) = 0;
234
235 if((*map_ptr).empty() == false) { (*map_ptr).clear(); }
236 }
237
238
239
240 template<typename eT>
241 inline
242 void
243 MapMat<eT>::set_size(const uword in_n_rows)
244 {
245 arma_extra_debug_sigprint();
246
247 init_warm(in_n_rows, 1);
248 }
249
250
251
252 template<typename eT>
253 inline
254 void
255 MapMat<eT>::set_size(const uword in_n_rows, const uword in_n_cols)
256 {
257 arma_extra_debug_sigprint();
258
259 init_warm(in_n_rows, in_n_cols);
260 }
261
262
263
264 template<typename eT>
265 inline
266 void
267 MapMat<eT>::set_size(const SizeMat& s)
268 {
269 arma_extra_debug_sigprint();
270
271 init_warm(s.n_rows, s.n_cols);
272 }
273
274
275
276 template<typename eT>
277 inline
278 void
279 MapMat<eT>::zeros()
280 {
281 arma_extra_debug_sigprint();
282
283 (*map_ptr).clear();
284 }
285
286
287
288 template<typename eT>
289 inline
290 void
291 MapMat<eT>::zeros(const uword in_n_rows)
292 {
293 arma_extra_debug_sigprint();
294
295 init_warm(in_n_rows, 1);
296
297 (*map_ptr).clear();
298 }
299
300
301
302 template<typename eT>
303 inline
304 void
305 MapMat<eT>::zeros(const uword in_n_rows, const uword in_n_cols)
306 {
307 arma_extra_debug_sigprint();
308
309 init_warm(in_n_rows, in_n_cols);
310
311 (*map_ptr).clear();
312 }
313
314
315
316 template<typename eT>
317 inline
318 void
319 MapMat<eT>::zeros(const SizeMat& s)
320 {
321 arma_extra_debug_sigprint();
322
323 init_warm(s.n_rows, s.n_cols);
324
325 (*map_ptr).clear();
326 }
327
328
329
330 template<typename eT>
331 inline
332 void
333 MapMat<eT>::eye()
334 {
335 arma_extra_debug_sigprint();
336
337 (*this).eye(n_rows, n_cols);
338 }
339
340
341
342 template<typename eT>
343 inline
344 void
345 MapMat<eT>::eye(const uword in_n_rows, const uword in_n_cols)
346 {
347 arma_extra_debug_sigprint();
348
349 zeros(in_n_rows, in_n_cols);
350
351 const uword N = (std::min)(in_n_rows, in_n_cols);
352
353 map_type& map_ref = (*map_ptr);
354
355 for(uword i=0; i<N; ++i)
356 {
357 const uword index = (in_n_rows * i) + i;
358
359 #if defined(ARMA_USE_CXX11)
360 map_ref.emplace_hint(map_ref.cend(), index, eT(1));
361 #else
362 map_ref.operator[](index) = eT(1);
363 #endif
364 }
365 }
366
367
368
369 template<typename eT>
370 inline
371 void
372 MapMat<eT>::eye(const SizeMat& s)
373 {
374 arma_extra_debug_sigprint();
375
376 (*this).eye(s.n_rows, s.n_cols);
377 }
378
379
380
381 template<typename eT>
382 inline
383 void
384 MapMat<eT>::speye()
385 {
386 arma_extra_debug_sigprint();
387
388 (*this).eye();
389 }
390
391
392
393 template<typename eT>
394 inline
395 void
396 MapMat<eT>::speye(const uword in_n_rows, const uword in_n_cols)
397 {
398 arma_extra_debug_sigprint();
399
400 (*this).eye(in_n_rows, in_n_cols);
401 }
402
403
404
405 template<typename eT>
406 inline
407 void
408 MapMat<eT>::speye(const SizeMat& s)
409 {
410 arma_extra_debug_sigprint();
411
412 (*this).eye(s);
413 }
414
415
416
417 template<typename eT>
418 arma_inline
419 arma_warn_unused
420 MapMat_val<eT>
421 MapMat<eT>::operator[](const uword index)
422 {
423 return MapMat_val<eT>(*this, index);
424 }
425
426
427
428 template<typename eT>
429 inline
430 arma_warn_unused
431 eT
432 MapMat<eT>::operator[](const uword index) const
433 {
434 map_type& map_ref = (*map_ptr);
435
436 typename map_type::const_iterator it = map_ref.find(index);
437 typename map_type::const_iterator it_end = map_ref.end();
438
439 return (it != it_end) ? eT((*it).second) : eT(0);
440 }
441
442
443
444 template<typename eT>
445 arma_inline
446 arma_warn_unused
447 MapMat_val<eT>
448 MapMat<eT>::operator()(const uword index)
449 {
450 arma_debug_check( (index >= n_elem), "MapMat::operator(): index out of bounds" );
451
452 return MapMat_val<eT>(*this, index);
453 }
454
455
456
457 template<typename eT>
458 inline
459 arma_warn_unused
460 eT
461 MapMat<eT>::operator()(const uword index) const
462 {
463 arma_debug_check( (index >= n_elem), "MapMat::operator(): index out of bounds" );
464
465 map_type& map_ref = (*map_ptr);
466
467 typename map_type::const_iterator it = map_ref.find(index);
468 typename map_type::const_iterator it_end = map_ref.end();
469
470 return (it != it_end) ? eT((*it).second) : eT(0);
471 }
472
473
474
475 template<typename eT>
476 arma_inline
477 arma_warn_unused
478 MapMat_val<eT>
479 MapMat<eT>::at(const uword in_row, const uword in_col)
480 {
481 const uword index = (n_rows * in_col) + in_row;
482
483 return MapMat_val<eT>(*this, index);
484 }
485
486
487
488 template<typename eT>
489 inline
490 arma_warn_unused
491 eT
492 MapMat<eT>::at(const uword in_row, const uword in_col) const
493 {
494 const uword index = (n_rows * in_col) + in_row;
495
496 map_type& map_ref = (*map_ptr);
497
498 typename map_type::const_iterator it = map_ref.find(index);
499 typename map_type::const_iterator it_end = map_ref.end();
500
501 return (it != it_end) ? eT((*it).second) : eT(0);
502 }
503
504
505
506 template<typename eT>
507 arma_inline
508 arma_warn_unused
509 MapMat_val<eT>
510 MapMat<eT>::operator()(const uword in_row, const uword in_col)
511 {
512 arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" );
513
514 const uword index = (n_rows * in_col) + in_row;
515
516 return MapMat_val<eT>(*this, index);
517 }
518
519
520
521 template<typename eT>
522 inline
523 arma_warn_unused
524 eT
525 MapMat<eT>::operator()(const uword in_row, const uword in_col) const
526 {
527 arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "MapMat::operator(): index out of bounds" );
528
529 const uword index = (n_rows * in_col) + in_row;
530
531 map_type& map_ref = (*map_ptr);
532
533 typename map_type::const_iterator it = map_ref.find(index);
534 typename map_type::const_iterator it_end = map_ref.end();
535
536 return (it != it_end) ? eT((*it).second) : eT(0);
537 }
538
539
540
541 template<typename eT>
542 inline
543 arma_warn_unused
544 bool
545 MapMat<eT>::is_empty() const
546 {
547 return (n_elem == 0);
548 }
549
550
551
552 template<typename eT>
553 inline
554 arma_warn_unused
555 bool
556 MapMat<eT>::is_vec() const
557 {
558 return ( (n_rows == 1) || (n_cols == 1) );
559 }
560
561
562
563 template<typename eT>
564 inline
565 arma_warn_unused
566 bool
567 MapMat<eT>::is_rowvec() const
568 {
569 return (n_rows == 1);
570 }
571
572
573
574 //! returns true if the object can be interpreted as a column vector
575 template<typename eT>
576 inline
577 arma_warn_unused
578 bool
579 MapMat<eT>::is_colvec() const
580 {
581 return (n_cols == 1);
582 }
583
584
585
586 template<typename eT>
587 inline
588 arma_warn_unused
589 bool
590 MapMat<eT>::is_square() const
591 {
592 return (n_rows == n_cols);
593 }
594
595
596
597 // this function is for debugging purposes only
598 template<typename eT>
599 inline
600 void
601 MapMat<eT>::sprandu(const uword in_n_rows, const uword in_n_cols, const double density)
602 {
603 arma_extra_debug_sigprint();
604
605 zeros(in_n_rows, in_n_cols);
606
607 const uword N = uword(density * double(n_elem));
608
609 const Col<eT> vals(N, fill::randu);
610 const Col<uword> indx = linspace< Col<uword> >(0, ((n_elem > 0) ? uword(n_elem-1) : uword(0)) , N);
611
612 const eT* vals_mem = vals.memptr();
613 const uword* indx_mem = indx.memptr();
614
615 map_type& map_ref = (*map_ptr);
616
617 for(uword i=0; i < N; ++i)
618 {
619 const uword index = indx_mem[i];
620 const eT val = vals_mem[i];
621
622 #if defined(ARMA_USE_CXX11)
623 map_ref.emplace_hint(map_ref.cend(), index, val);
624 #else
625 map_ref.operator[](index) = val;
626 #endif
627 }
628 }
629
630
631
632 // this function is for debugging purposes only
633 template<typename eT>
634 inline
635 void
636 MapMat<eT>::print(const std::string& extra_text) const
637 {
638 arma_extra_debug_sigprint();
639
640 if(extra_text.length() != 0)
641 {
642 const std::streamsize orig_width = get_cout_stream().width();
643
644 get_cout_stream() << extra_text << '\n';
645
646 get_cout_stream().width(orig_width);
647 }
648
649 map_type& map_ref = (*map_ptr);
650
651 const uword n_nonzero = uword(map_ref.size());
652
653 const double density = (n_elem > 0) ? ((double(n_nonzero) / double(n_elem))*double(100)) : double(0);
654
655 get_cout_stream()
656 << "[matrix size: " << n_rows << 'x' << n_cols << "; n_nonzero: " << n_nonzero
657 << "; density: " << density << "%]\n\n";
658
659 if(n_nonzero > 0)
660 {
661 typename map_type::const_iterator it = map_ref.begin();
662
663 for(uword i=0; i < n_nonzero; ++i)
664 {
665 const std::pair<uword, eT>& entry = (*it);
666
667 const uword index = entry.first;
668 const eT val = entry.second;
669
670 const uword row = index % n_rows;
671 const uword col = index / n_rows;
672
673 get_cout_stream() << '(' << row << ", " << col << ") ";
674 get_cout_stream() << val << '\n';
675
676 ++it;
677 }
678 }
679
680 get_cout_stream().flush();
681 }
682
683
684
685 template<typename eT>
686 inline
687 uword
688 MapMat<eT>::get_n_nonzero() const
689 {
690 arma_extra_debug_sigprint();
691
692 return uword((*map_ptr).size());
693 }
694
695
696
697 template<typename eT>
698 inline
699 void
700 MapMat<eT>::get_locval_format(umat& locs, Col<eT>& vals) const
701 {
702 arma_extra_debug_sigprint();
703
704 map_type& map_ref = (*map_ptr);
705
706 typename map_type::const_iterator it = map_ref.begin();
707
708 const uword N = uword(map_ref.size());
709
710 locs.set_size(2,N);
711 vals.set_size(N);
712
713 eT* vals_mem = vals.memptr();
714
715 for(uword i=0; i<N; ++i)
716 {
717 const std::pair<uword, eT>& entry = (*it);
718
719 const uword index = entry.first;
720 const eT val = entry.second;
721
722 const uword row = index % n_rows;
723 const uword col = index / n_rows;
724
725 uword* locs_colptr = locs.colptr(i);
726
727 locs_colptr[0] = row;
728 locs_colptr[1] = col;
729
730 vals_mem[i] = val;
731
732 ++it;
733 }
734 }
735
736
737
738 template<typename eT>
739 inline
740 void
741 MapMat<eT>::init_cold()
742 {
743 arma_extra_debug_sigprint();
744
745 // ensure that n_elem can hold the result of (n_rows * n_cols)
746
747 #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD))
748 const char* error_message = "MapMat(): requested size is too large";
749 #else
750 const char* error_message = "MapMat(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD";
751 #endif
752
753 arma_debug_check
754 (
755 (
756 ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
757 ? ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) )
758 : false
759 ),
760 error_message
761 );
762
763 map_ptr = new (std::nothrow) map_type;
764
765 arma_check_bad_alloc( (map_ptr == NULL), "MapMat(): out of memory" );
766 }
767
768
769
770 template<typename eT>
771 inline
772 void
773 MapMat<eT>::init_warm(const uword in_n_rows, const uword in_n_cols)
774 {
775 arma_extra_debug_sigprint();
776
777 if( (n_rows == in_n_rows) && (n_cols == in_n_cols)) { return; }
778
779 // ensure that n_elem can hold the result of (n_rows * n_cols)
780
781 #if (defined(ARMA_USE_CXX11) || defined(ARMA_64BIT_WORD))
782 const char* error_message = "MapMat(): requested size is too large";
783 #else
784 const char* error_message = "MapMat(): requested size is too large; suggest to compile in C++11 mode or enable ARMA_64BIT_WORD";
785 #endif
786
787 arma_debug_check
788 (
789 (
790 ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
791 ? ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) )
792 : false
793 ),
794 error_message
795 );
796
797 const uword new_n_elem = in_n_rows * in_n_cols;
798
799 access::rw(n_rows) = in_n_rows;
800 access::rw(n_cols) = in_n_cols;
801 access::rw(n_elem) = new_n_elem;
802
803 if(new_n_elem == 0) { (*map_ptr).clear(); }
804 }
805
806
807
808 template<typename eT>
809 arma_inline
810 void
811 MapMat<eT>::set_val(const uword index, const eT& in_val)
812 {
813 arma_extra_debug_sigprint();
814
815 if(in_val != eT(0))
816 {
817 #if defined(ARMA_USE_CXX11)
818 {
819 map_type& map_ref = (*map_ptr);
820
821 if( (map_ref.empty() == false) && (index > uword(map_ref.crbegin()->first)) )
822 {
823 map_ref.emplace_hint(map_ref.cend(), index, in_val);
824 }
825 else
826 {
827 map_ref.operator[](index) = in_val;
828 }
829 }
830 #else
831 {
832 (*map_ptr).operator[](index) = in_val;
833 }
834 #endif
835 }
836 else
837 {
838 (*this).erase_val(index);
839 }
840 }
841
842
843
844 template<typename eT>
845 inline
846 void
847 MapMat<eT>::erase_val(const uword index)
848 {
849 arma_extra_debug_sigprint();
850
851 map_type& map_ref = (*map_ptr);
852
853 typename map_type::iterator it = map_ref.find(index);
854 typename map_type::iterator it_end = map_ref.end();
855
856 if(it != it_end) { map_ref.erase(it); }
857 }
858
859
860
861
862
863
864 // MapMat_val
865
866
867
868 template<typename eT>
869 arma_inline
870 MapMat_val<eT>::MapMat_val(MapMat<eT>& in_parent, const uword in_index)
871 : parent(in_parent)
872 , index (in_index )
873 {
874 arma_extra_debug_sigprint();
875 }
876
877
878
879 template<typename eT>
880 arma_inline
881 MapMat_val<eT>::operator eT() const
882 {
883 arma_extra_debug_sigprint();
884
885 const MapMat<eT>& const_parent = parent;
886
887 return const_parent.operator[](index);
888 }
889
890
891
892 template<typename eT>
893 arma_inline
894 typename get_pod_type<eT>::result
895 MapMat_val<eT>::real() const
896 {
897 arma_extra_debug_sigprint();
898
899 typedef typename get_pod_type<eT>::result T;
900
901 const MapMat<eT>& const_parent = parent;
902
903 return T( access::tmp_real( const_parent.operator[](index) ) );
904 }
905
906
907
908 template<typename eT>
909 arma_inline
910 typename get_pod_type<eT>::result
911 MapMat_val<eT>::imag() const
912 {
913 arma_extra_debug_sigprint();
914
915 typedef typename get_pod_type<eT>::result T;
916
917 const MapMat<eT>& const_parent = parent;
918
919 return T( access::tmp_imag( const_parent.operator[](index) ) );
920 }
921
922
923
924 template<typename eT>
925 arma_inline
926 void
927 MapMat_val<eT>::operator=(const MapMat_val<eT>& x)
928 {
929 arma_extra_debug_sigprint();
930
931 const eT in_val = eT(x);
932
933 parent.set_val(index, in_val);
934 }
935
936
937
938 template<typename eT>
939 arma_inline
940 void
941 MapMat_val<eT>::operator=(const eT in_val)
942 {
943 arma_extra_debug_sigprint();
944
945 parent.set_val(index, in_val);
946 }
947
948
949
950 template<typename eT>
951 arma_inline
952 void
953 MapMat_val<eT>::operator+=(const eT in_val)
954 {
955 arma_extra_debug_sigprint();
956
957 typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
958
959 if(in_val != eT(0))
960 {
961 eT& val = map_ref.operator[](index); // creates the element if it doesn't exist
962
963 val += in_val;
964
965 if(val == eT(0)) { map_ref.erase(index); }
966 }
967 }
968
969
970
971 template<typename eT>
972 arma_inline
973 void
974 MapMat_val<eT>::operator-=(const eT in_val)
975 {
976 arma_extra_debug_sigprint();
977
978 typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
979
980 if(in_val != eT(0))
981 {
982 eT& val = map_ref.operator[](index); // creates the element if it doesn't exist
983
984 val -= in_val;
985
986 if(val == eT(0)) { map_ref.erase(index); }
987 }
988 }
989
990
991
992 template<typename eT>
993 arma_inline
994 void
995 MapMat_val<eT>::operator*=(const eT in_val)
996 {
997 arma_extra_debug_sigprint();
998
999 typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
1000
1001 typename MapMat<eT>::map_type::iterator it = map_ref.find(index);
1002 typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
1003
1004 if(it != it_end)
1005 {
1006 if(in_val != eT(0))
1007 {
1008 eT& val = (*it).second;
1009
1010 val *= in_val;
1011
1012 if(val == eT(0)) { map_ref.erase(it); }
1013 }
1014 else
1015 {
1016 map_ref.erase(it);
1017 }
1018 }
1019 }
1020
1021
1022
1023 template<typename eT>
1024 arma_inline
1025 void
1026 MapMat_val<eT>::operator/=(const eT in_val)
1027 {
1028 arma_extra_debug_sigprint();
1029
1030 typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
1031
1032 typename MapMat<eT>::map_type::iterator it = map_ref.find(index);
1033 typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
1034
1035 if(it != it_end)
1036 {
1037 eT& val = (*it).second;
1038
1039 val /= in_val;
1040
1041 if(val == eT(0)) { map_ref.erase(it); }
1042 }
1043 else
1044 {
1045 // silly operation, but included for completness
1046
1047 const eT val = eT(0) / in_val;
1048
1049 if(val != eT(0)) { parent.set_val(index, val); }
1050 }
1051 }
1052
1053
1054
1055 template<typename eT>
1056 arma_inline
1057 void
1058 MapMat_val<eT>::operator++()
1059 {
1060 arma_extra_debug_sigprint();
1061
1062 typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
1063
1064 eT& val = map_ref.operator[](index); // creates the element if it doesn't exist
1065
1066 val += eT(1); // can't use ++, as eT can be std::complex
1067
1068 if(val == eT(0)) { map_ref.erase(index); }
1069 }
1070
1071
1072
1073 template<typename eT>
1074 arma_inline
1075 void
1076 MapMat_val<eT>::operator++(int)
1077 {
1078 arma_extra_debug_sigprint();
1079
1080 (*this).operator++();
1081 }
1082
1083
1084
1085 template<typename eT>
1086 arma_inline
1087 void
1088 MapMat_val<eT>::operator--()
1089 {
1090 arma_extra_debug_sigprint();
1091
1092 typename MapMat<eT>::map_type& map_ref = *(parent.map_ptr);
1093
1094 eT& val = map_ref.operator[](index); // creates the element if it doesn't exist
1095
1096 val -= eT(1); // can't use --, as eT can be std::complex
1097
1098 if(val == eT(0)) { map_ref.erase(index); }
1099 }
1100
1101
1102
1103 template<typename eT>
1104 arma_inline
1105 void
1106 MapMat_val<eT>::operator--(int)
1107 {
1108 arma_extra_debug_sigprint();
1109
1110 (*this).operator--();
1111 }
1112
1113
1114
1115
1116
1117 // SpMat_MapMat_val
1118
1119
1120
1121 template<typename eT>
1122 arma_inline
1123 SpMat_MapMat_val<eT>::SpMat_MapMat_val(SpMat<eT>& in_s_parent, MapMat<eT>& in_m_parent, const uword in_row, const uword in_col)
1124 : s_parent(in_s_parent)
1125 , m_parent(in_m_parent)
1126 , row (in_row )
1127 , col (in_col )
1128 {
1129 arma_extra_debug_sigprint();
1130 }
1131
1132
1133
1134 template<typename eT>
1135 inline
1136 SpMat_MapMat_val<eT>::operator eT() const
1137 {
1138 arma_extra_debug_sigprint();
1139
1140 const SpMat<eT>& const_s_parent = s_parent; // declare as const for clarity of intent
1141
1142 return const_s_parent.get_value(row,col);
1143 }
1144
1145
1146
1147 template<typename eT>
1148 inline
1149 typename get_pod_type<eT>::result
1150 SpMat_MapMat_val<eT>::real() const
1151 {
1152 arma_extra_debug_sigprint();
1153
1154 typedef typename get_pod_type<eT>::result T;
1155
1156 const SpMat<eT>& const_s_parent = s_parent; // declare as const for clarity of intent
1157
1158 return T( access::tmp_real( const_s_parent.get_value(row,col) ) );
1159 }
1160
1161
1162
1163 template<typename eT>
1164 inline
1165 typename get_pod_type<eT>::result
1166 SpMat_MapMat_val<eT>::imag() const
1167 {
1168 arma_extra_debug_sigprint();
1169
1170 typedef typename get_pod_type<eT>::result T;
1171
1172 const SpMat<eT>& const_s_parent = s_parent; // declare as const for clarity of intent
1173
1174 return T( access::tmp_imag( const_s_parent.get_value(row,col) ) );
1175 }
1176
1177
1178
1179 template<typename eT>
1180 inline
1181 SpMat_MapMat_val<eT>&
1182 SpMat_MapMat_val<eT>::operator=(const SpMat_MapMat_val<eT>& x)
1183 {
1184 arma_extra_debug_sigprint();
1185
1186 const eT in_val = eT(x);
1187
1188 return (*this).operator=(in_val);
1189 }
1190
1191
1192
1193 template<typename eT>
1194 inline
1195 SpMat_MapMat_val<eT>&
1196 SpMat_MapMat_val<eT>::operator=(const eT in_val)
1197 {
1198 arma_extra_debug_sigprint();
1199
1200 #if defined(ARMA_USE_OPENMP)
1201 {
1202 #pragma omp critical (arma_SpMat_cache)
1203 {
1204 (*this).set(in_val);
1205 }
1206 }
1207 #elif defined(ARMA_USE_CXX11)
1208 {
1209 s_parent.cache_mutex.lock();
1210
1211 (*this).set(in_val);
1212
1213 s_parent.cache_mutex.unlock();
1214 }
1215 #else
1216 {
1217 (*this).set(in_val);
1218 }
1219 #endif
1220
1221 return *this;
1222 }
1223
1224
1225
1226 template<typename eT>
1227 inline
1228 SpMat_MapMat_val<eT>&
1229 SpMat_MapMat_val<eT>::operator+=(const eT in_val)
1230 {
1231 arma_extra_debug_sigprint();
1232
1233 if(in_val == eT(0)) { return *this; }
1234
1235 #if defined(ARMA_USE_OPENMP)
1236 {
1237 #pragma omp critical (arma_SpMat_cache)
1238 {
1239 (*this).add(in_val);
1240 }
1241 }
1242 #elif defined(ARMA_USE_CXX11)
1243 {
1244 s_parent.cache_mutex.lock();
1245
1246 (*this).add(in_val);
1247
1248 s_parent.cache_mutex.unlock();
1249 }
1250 #else
1251 {
1252 (*this).add(in_val);
1253 }
1254 #endif
1255
1256 return *this;
1257 }
1258
1259
1260
1261 template<typename eT>
1262 inline
1263 SpMat_MapMat_val<eT>&
1264 SpMat_MapMat_val<eT>::operator-=(const eT in_val)
1265 {
1266 arma_extra_debug_sigprint();
1267
1268 if(in_val == eT(0)) { return *this; }
1269
1270 #if defined(ARMA_USE_OPENMP)
1271 {
1272 #pragma omp critical (arma_SpMat_cache)
1273 {
1274 (*this).sub(in_val);
1275 }
1276 }
1277 #elif defined(ARMA_USE_CXX11)
1278 {
1279 s_parent.cache_mutex.lock();
1280
1281 (*this).sub(in_val);
1282
1283 s_parent.cache_mutex.unlock();
1284 }
1285 #else
1286 {
1287 (*this).sub(in_val);
1288 }
1289 #endif
1290
1291 return *this;
1292 }
1293
1294
1295
1296 template<typename eT>
1297 inline
1298 SpMat_MapMat_val<eT>&
1299 SpMat_MapMat_val<eT>::operator*=(const eT in_val)
1300 {
1301 arma_extra_debug_sigprint();
1302
1303 #if defined(ARMA_USE_OPENMP)
1304 {
1305 #pragma omp critical (arma_SpMat_cache)
1306 {
1307 (*this).mul(in_val);
1308 }
1309 }
1310 #elif defined(ARMA_USE_CXX11)
1311 {
1312 s_parent.cache_mutex.lock();
1313
1314 (*this).mul(in_val);
1315
1316 s_parent.cache_mutex.unlock();
1317 }
1318 #else
1319 {
1320 (*this).mul(in_val);
1321 }
1322 #endif
1323
1324 return *this;
1325 }
1326
1327
1328
1329 template<typename eT>
1330 inline
1331 SpMat_MapMat_val<eT>&
1332 SpMat_MapMat_val<eT>::operator/=(const eT in_val)
1333 {
1334 arma_extra_debug_sigprint();
1335
1336 #if defined(ARMA_USE_OPENMP)
1337 {
1338 #pragma omp critical (arma_SpMat_cache)
1339 {
1340 (*this).div(in_val);
1341 }
1342 }
1343 #elif defined(ARMA_USE_CXX11)
1344 {
1345 s_parent.cache_mutex.lock();
1346
1347 (*this).div(in_val);
1348
1349 s_parent.cache_mutex.unlock();
1350 }
1351 #else
1352 {
1353 (*this).div(in_val);
1354 }
1355 #endif
1356
1357 return *this;
1358 }
1359
1360
1361
1362 template<typename eT>
1363 inline
1364 SpMat_MapMat_val<eT>&
1365 SpMat_MapMat_val<eT>::operator++()
1366 {
1367 arma_extra_debug_sigprint();
1368
1369 return (*this).operator+=( eT(1) );
1370 }
1371
1372
1373
1374 template<typename eT>
1375 inline
1376 arma_warn_unused
1377 eT
1378 SpMat_MapMat_val<eT>::operator++(int)
1379 {
1380 arma_extra_debug_sigprint();
1381
1382 const eT old_val = eT(*this);
1383
1384 (*this).operator+=( eT(1) );
1385
1386 return old_val;
1387 }
1388
1389
1390
1391 template<typename eT>
1392 inline
1393 SpMat_MapMat_val<eT>&
1394 SpMat_MapMat_val<eT>::operator--()
1395 {
1396 arma_extra_debug_sigprint();
1397
1398 return (*this).operator-=( eT(1) );
1399 }
1400
1401
1402
1403 template<typename eT>
1404 inline
1405 arma_warn_unused
1406 eT
1407 SpMat_MapMat_val<eT>::operator--(int)
1408 {
1409 arma_extra_debug_sigprint();
1410
1411 const eT old_val = eT(*this);
1412
1413 (*this).operator-=( eT(1) );
1414
1415 return old_val;
1416 }
1417
1418
1419
1420 template<typename eT>
1421 inline
1422 void
1423 SpMat_MapMat_val<eT>::set(const eT in_val)
1424 {
1425 arma_extra_debug_sigprint();
1426
1427 const bool done = (s_parent.sync_state == 0) ? s_parent.try_set_value_csc(row, col, in_val) : false;
1428
1429 if(done == false)
1430 {
1431 s_parent.sync_cache_simple();
1432
1433 const uword index = (m_parent.n_rows * col) + row;
1434
1435 m_parent.set_val(index, in_val);
1436
1437 s_parent.sync_state = 1;
1438
1439 access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
1440 }
1441 }
1442
1443
1444
1445 template<typename eT>
1446 inline
1447 void
1448 SpMat_MapMat_val<eT>::add(const eT in_val)
1449 {
1450 arma_extra_debug_sigprint();
1451
1452 const bool done = (s_parent.sync_state == 0) ? s_parent.try_add_value_csc(row, col, in_val) : false;
1453
1454 if(done == false)
1455 {
1456 s_parent.sync_cache_simple();
1457
1458 const uword index = (m_parent.n_rows * col) + row;
1459
1460 typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
1461
1462 eT& val = map_ref.operator[](index); // creates the element if it doesn't exist
1463
1464 val += in_val;
1465
1466 if(val == eT(0)) { map_ref.erase(index); }
1467
1468 s_parent.sync_state = 1;
1469
1470 access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
1471 }
1472 }
1473
1474
1475
1476 template<typename eT>
1477 inline
1478 void
1479 SpMat_MapMat_val<eT>::sub(const eT in_val)
1480 {
1481 arma_extra_debug_sigprint();
1482
1483 const bool done = (s_parent.sync_state == 0) ? s_parent.try_sub_value_csc(row, col, in_val) : false;
1484
1485 if(done == false)
1486 {
1487 s_parent.sync_cache_simple();
1488
1489 const uword index = (m_parent.n_rows * col) + row;
1490
1491 typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
1492
1493 eT& val = map_ref.operator[](index); // creates the element if it doesn't exist
1494
1495 val -= in_val;
1496
1497 if(val == eT(0)) { map_ref.erase(index); }
1498
1499 s_parent.sync_state = 1;
1500
1501 access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
1502 }
1503 }
1504
1505
1506
1507 template<typename eT>
1508 inline
1509 void
1510 SpMat_MapMat_val<eT>::mul(const eT in_val)
1511 {
1512 arma_extra_debug_sigprint();
1513
1514 const bool done = (s_parent.sync_state == 0) ? s_parent.try_mul_value_csc(row, col, in_val) : false;
1515
1516 if(done == false)
1517 {
1518 s_parent.sync_cache_simple();
1519
1520 const uword index = (m_parent.n_rows * col) + row;
1521
1522 typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
1523
1524 typename MapMat<eT>::map_type::iterator it = map_ref.find(index);
1525 typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
1526
1527 if(it != it_end)
1528 {
1529 if(in_val != eT(0))
1530 {
1531 eT& val = (*it).second;
1532
1533 val *= in_val;
1534
1535 if(val == eT(0)) { map_ref.erase(it); }
1536 }
1537 else
1538 {
1539 map_ref.erase(it);
1540 }
1541
1542 s_parent.sync_state = 1;
1543
1544 access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
1545 }
1546 else
1547 {
1548 // element not found, ie. it's zero; zero multiplied by anything is zero, except for nan and inf
1549 if(arma_isfinite(in_val) == false)
1550 {
1551 const eT result = eT(0) * in_val;
1552
1553 if(result != eT(0)) // paranoia, in case compiling with -ffast-math
1554 {
1555 m_parent.set_val(index, result);
1556
1557 s_parent.sync_state = 1;
1558
1559 access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
1560 }
1561 }
1562 }
1563 }
1564 }
1565
1566
1567
1568 template<typename eT>
1569 inline
1570 void
1571 SpMat_MapMat_val<eT>::div(const eT in_val)
1572 {
1573 arma_extra_debug_sigprint();
1574
1575 const bool done = (s_parent.sync_state == 0) ? s_parent.try_div_value_csc(row, col, in_val) : false;
1576
1577 if(done == false)
1578 {
1579 s_parent.sync_cache_simple();
1580
1581 const uword index = (m_parent.n_rows * col) + row;
1582
1583 typename MapMat<eT>::map_type& map_ref = *(m_parent.map_ptr);
1584
1585 typename MapMat<eT>::map_type::iterator it = map_ref.find(index);
1586 typename MapMat<eT>::map_type::iterator it_end = map_ref.end();
1587
1588 if(it != it_end)
1589 {
1590 eT& val = (*it).second;
1591
1592 val /= in_val;
1593
1594 if(val == eT(0)) { map_ref.erase(it); }
1595
1596 s_parent.sync_state = 1;
1597
1598 access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
1599 }
1600 else
1601 {
1602 // element not found, ie. it's zero; zero divided by anything is zero, except for zero and nan
1603 if( (in_val == eT(0)) || (arma_isnan(in_val)) )
1604 {
1605 const eT result = eT(0) / in_val;
1606
1607 if(result != eT(0)) // paranoia, in case compiling with -ffast-math
1608 {
1609 m_parent.set_val(index, result);
1610
1611 s_parent.sync_state = 1;
1612
1613 access::rw(s_parent.n_nonzero) = m_parent.get_n_nonzero();
1614 }
1615 }
1616 }
1617 }
1618 }
1619
1620
1621
1622
1623 // SpSubview_MapMat_val
1624
1625
1626
1627 template<typename eT>
1628 arma_inline
1629 SpSubview_MapMat_val<eT>::SpSubview_MapMat_val(SpSubview<eT>& in_sv_parent, MapMat<eT>& in_m_parent, const uword in_row, const uword in_col)
1630 : SpMat_MapMat_val<eT>(access::rw(in_sv_parent.m), in_m_parent, in_row, in_col)
1631 , sv_parent(in_sv_parent)
1632 {
1633 arma_extra_debug_sigprint();
1634 }
1635
1636
1637
1638 template<typename eT>
1639 inline
1640 SpSubview_MapMat_val<eT>&
1641 SpSubview_MapMat_val<eT>::operator=(const SpSubview_MapMat_val<eT>& x)
1642 {
1643 arma_extra_debug_sigprint();
1644
1645 const eT in_val = eT(x);
1646
1647 return (*this).operator=(in_val);
1648 }
1649
1650
1651
1652 template<typename eT>
1653 inline
1654 SpSubview_MapMat_val<eT>&
1655 SpSubview_MapMat_val<eT>::operator=(const eT in_val)
1656 {
1657 arma_extra_debug_sigprint();
1658
1659 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1660
1661 SpMat_MapMat_val<eT>::operator=(in_val);
1662
1663 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1664 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1665
1666 return *this;
1667 }
1668
1669
1670
1671 template<typename eT>
1672 inline
1673 SpSubview_MapMat_val<eT>&
1674 SpSubview_MapMat_val<eT>::operator+=(const eT in_val)
1675 {
1676 arma_extra_debug_sigprint();
1677
1678 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1679
1680 SpMat_MapMat_val<eT>::operator+=(in_val);
1681
1682 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1683 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1684
1685 return *this;
1686 }
1687
1688
1689
1690 template<typename eT>
1691 inline
1692 SpSubview_MapMat_val<eT>&
1693 SpSubview_MapMat_val<eT>::operator-=(const eT in_val)
1694 {
1695 arma_extra_debug_sigprint();
1696
1697 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1698
1699 SpMat_MapMat_val<eT>::operator-=(in_val);
1700
1701 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1702 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1703
1704 return *this;
1705 }
1706
1707
1708
1709 template<typename eT>
1710 inline
1711 SpSubview_MapMat_val<eT>&
1712 SpSubview_MapMat_val<eT>::operator*=(const eT in_val)
1713 {
1714 arma_extra_debug_sigprint();
1715
1716 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1717
1718 SpMat_MapMat_val<eT>::operator*=(in_val);
1719
1720 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1721 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1722
1723 return *this;
1724 }
1725
1726
1727
1728 template<typename eT>
1729 inline
1730 SpSubview_MapMat_val<eT>&
1731 SpSubview_MapMat_val<eT>::operator/=(const eT in_val)
1732 {
1733 arma_extra_debug_sigprint();
1734
1735 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1736
1737 SpMat_MapMat_val<eT>::operator/=(in_val);
1738
1739 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1740 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1741
1742 return *this;
1743 }
1744
1745
1746
1747 template<typename eT>
1748 inline
1749 SpSubview_MapMat_val<eT>&
1750 SpSubview_MapMat_val<eT>::operator++()
1751 {
1752 arma_extra_debug_sigprint();
1753
1754 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1755
1756 SpMat_MapMat_val<eT>::operator++();
1757
1758 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1759 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1760
1761 return *this;
1762 }
1763
1764
1765
1766 template<typename eT>
1767 inline
1768 arma_warn_unused
1769 eT
1770 SpSubview_MapMat_val<eT>::operator++(int)
1771 {
1772 arma_extra_debug_sigprint();
1773
1774 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1775
1776 const eT old_val = SpMat_MapMat_val<eT>::operator++(int(0));
1777
1778 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1779 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1780
1781 return old_val;
1782 }
1783
1784
1785
1786 template<typename eT>
1787 inline
1788 SpSubview_MapMat_val<eT>&
1789 SpSubview_MapMat_val<eT>::operator--()
1790 {
1791 arma_extra_debug_sigprint();
1792
1793 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1794
1795 SpMat_MapMat_val<eT>::operator--();
1796
1797 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1798 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1799
1800 return *this;
1801 }
1802
1803
1804
1805 template<typename eT>
1806 inline
1807 arma_warn_unused
1808 eT
1809 SpSubview_MapMat_val<eT>::operator--(int)
1810 {
1811 arma_extra_debug_sigprint();
1812
1813 const uword old_n_nonzero = sv_parent.m.n_nonzero;
1814
1815 const eT old_val = SpMat_MapMat_val<eT>::operator--(int(0));
1816
1817 if(sv_parent.m.n_nonzero > old_n_nonzero) { access::rw(sv_parent.n_nonzero)++; }
1818 if(sv_parent.m.n_nonzero < old_n_nonzero) { access::rw(sv_parent.n_nonzero)--; }
1819
1820 return old_val;
1821 }
1822
1823
1824
1825 //! @}