comparison armadillo-2.4.4/include/armadillo_bits/Mat_meat.hpp @ 0:8b6102e2a9b0

Armadillo Library
author maxzanoni76 <max.zanoni@eecs.qmul.ac.uk>
date Wed, 11 Apr 2012 09:27:06 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8b6102e2a9b0
1 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
2 // Copyright (C) 2008-2011 Conrad Sanderson
3 //
4 // This file is part of the Armadillo C++ library.
5 // It is provided without any warranty of fitness
6 // for any purpose. You can redistribute this file
7 // and/or modify it under the terms of the GNU
8 // Lesser General Public License (LGPL) as published
9 // by the Free Software Foundation, either version 3
10 // of the License or (at your option) any later version.
11 // (see http://www.opensource.org/licenses for more info)
12
13
14 //! \addtogroup Mat
15 //! @{
16
17
18 template<typename eT>
19 inline
20 Mat<eT>::~Mat()
21 {
22 arma_extra_debug_sigprint_this(this);
23
24 if(mem_state == 0)
25 {
26 if(n_elem > arma_config::mat_prealloc)
27 {
28 #if defined(ARMA_USE_TBB_ALLOC)
29 scalable_free((void *)(mem));
30 #else
31 delete [] mem;
32 #endif
33 }
34 }
35
36 if(arma_config::debug == true)
37 {
38 // try to expose buggy user code that accesses deleted objects
39 access::rw(n_rows) = 0;
40 access::rw(n_cols) = 0;
41 access::rw(n_elem) = 0;
42 access::rw(mem) = 0;
43 }
44
45 arma_type_check(( is_supported_elem_type<eT>::value == false ));
46 }
47
48
49
50 template<typename eT>
51 inline
52 Mat<eT>::Mat()
53 : n_rows(0)
54 , n_cols(0)
55 , n_elem(0)
56 , vec_state(0)
57 , mem_state(0)
58 , mem()
59 {
60 arma_extra_debug_sigprint_this(this);
61 }
62
63
64
65 //! construct the matrix to have user specified dimensions
66 template<typename eT>
67 inline
68 Mat<eT>::Mat(const uword in_n_rows, const uword in_n_cols)
69 : n_rows(in_n_rows)
70 , n_cols(in_n_cols)
71 , n_elem(in_n_rows*in_n_cols)
72 , vec_state(0)
73 , mem_state(0)
74 , mem()
75 {
76 arma_extra_debug_sigprint_this(this);
77
78 init_cold();
79 }
80
81
82
83 template<typename eT>
84 inline
85 void
86 Mat<eT>::init_cold()
87 {
88 arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d") % n_rows % n_cols );
89
90 // ensure that n_elem can hold the result of (n_rows * n_cols)
91
92 arma_debug_check
93 (
94 (
95 ( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
96 ? ( (float(n_rows) * float(n_cols)) > float(ARMA_MAX_UWORD) )
97 : false
98 ),
99 "Mat::init(): requested size is too large"
100 );
101
102 if(n_elem <= arma_config::mat_prealloc)
103 {
104 access::rw(mem) = mem_local;
105 }
106 else
107 {
108 arma_extra_debug_print("Mat::init(): allocating memory");
109
110 #if defined(ARMA_USE_TBB_ALLOC)
111 access::rw(mem) = (eT *) scalable_malloc(sizeof(eT)*n_elem);
112 #else
113 access::rw(mem) = new(std::nothrow) eT[n_elem];
114 #endif
115
116 arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
117 }
118 }
119
120
121
122 //! internal matrix construction; if the requested size is small enough, memory from the stack is used. otherwise memory is allocated via 'new'
123 template<typename eT>
124 inline
125 void
126 Mat<eT>::init_warm(uword in_n_rows, uword in_n_cols)
127 {
128 arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d") % in_n_rows % in_n_cols );
129
130 if( (n_rows == in_n_rows) && (n_cols == in_n_cols) )
131 {
132 return;
133 }
134
135 bool err_state = false;
136 char* err_msg = 0;
137
138 const uhword t_vec_state = vec_state;
139 const uhword t_mem_state = mem_state;
140
141 arma_debug_set_error
142 (
143 err_state,
144 err_msg,
145 (t_mem_state == 3),
146 "Mat::init(): size is fixed and hence cannot be changed"
147 );
148
149 if(t_vec_state > 0)
150 {
151 if( (in_n_rows == 0) && (in_n_cols == 0) )
152 {
153 if(t_vec_state == 1)
154 {
155 in_n_cols = 1;
156 }
157 else
158 if(t_vec_state == 2)
159 {
160 in_n_rows = 1;
161 }
162 }
163 else
164 {
165 arma_debug_set_error
166 (
167 err_state,
168 err_msg,
169 ( ((t_vec_state == 1) && (in_n_cols != 1)) || ((t_vec_state == 2) && (in_n_rows != 1)) ),
170 "Mat::init(): object is a vector; requested size is not compatible"
171 );
172 }
173 }
174
175 // ensure that n_elem can hold the result of (n_rows * n_cols)
176
177 arma_debug_set_error
178 (
179 err_state,
180 err_msg,
181 (
182 ( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
183 ? ( (float(in_n_rows) * float(in_n_cols)) > float(ARMA_MAX_UWORD) )
184 : false
185 ),
186 "Mat::init(): requested size is too large"
187 );
188
189 arma_debug_check(err_state, err_msg);
190
191 const uword old_n_elem = n_elem;
192 const uword new_n_elem = in_n_rows * in_n_cols;
193
194 if(old_n_elem == new_n_elem)
195 {
196 arma_extra_debug_print("Mat::init(): reusing memory");
197
198 access::rw(n_rows) = in_n_rows;
199 access::rw(n_cols) = in_n_cols;
200 }
201 else
202 {
203 arma_debug_check
204 (
205 (t_mem_state == 2),
206 "Mat::init(): mismatch between size of auxiliary memory and requested size"
207 );
208
209 if(t_mem_state == 0)
210 {
211 if(old_n_elem > arma_config::mat_prealloc)
212 {
213 arma_extra_debug_print("Mat::init(): freeing memory");
214
215 #if defined(ARMA_USE_TBB_ALLOC)
216 scalable_free((void *)(mem));
217 #else
218 delete [] mem;
219 #endif
220 }
221 }
222
223
224 if(new_n_elem <= arma_config::mat_prealloc)
225 {
226 access::rw(mem) = mem_local;
227 }
228 else
229 {
230 arma_extra_debug_print("Mat::init(): allocating memory");
231
232 #if defined(ARMA_USE_TBB_ALLOC)
233 access::rw(mem) = (eT *) scalable_malloc(sizeof(eT)*new_n_elem);
234 #else
235 access::rw(mem) = new(std::nothrow) eT[new_n_elem];
236 #endif
237
238 arma_check_bad_alloc( (mem == 0), "Mat::init(): out of memory" );
239 }
240
241 access::rw(n_rows) = in_n_rows;
242 access::rw(n_cols) = in_n_cols;
243 access::rw(n_elem) = new_n_elem;
244 access::rw(mem_state) = 0;
245 }
246 }
247
248
249
250 //! create the matrix from a textual description
251 template<typename eT>
252 inline
253 Mat<eT>::Mat(const char* text)
254 : n_rows(0)
255 , n_cols(0)
256 , n_elem(0)
257 , vec_state(0)
258 , mem_state(0)
259 , mem()
260 {
261 arma_extra_debug_sigprint_this(this);
262
263 init( std::string(text) );
264 }
265
266
267
268 //! create the matrix from a textual description
269 template<typename eT>
270 inline
271 const Mat<eT>&
272 Mat<eT>::operator=(const char* text)
273 {
274 arma_extra_debug_sigprint();
275
276 init( std::string(text) );
277 return *this;
278 }
279
280
281
282 //! create the matrix from a textual description
283 template<typename eT>
284 inline
285 Mat<eT>::Mat(const std::string& text)
286 : n_rows(0)
287 , n_cols(0)
288 , n_elem(0)
289 , vec_state(0)
290 , mem_state(0)
291 , mem()
292 {
293 arma_extra_debug_sigprint_this(this);
294
295 init(text);
296 }
297
298
299
300 //! create the matrix from a textual description
301 template<typename eT>
302 inline
303 const Mat<eT>&
304 Mat<eT>::operator=(const std::string& text)
305 {
306 arma_extra_debug_sigprint();
307
308 init(text);
309 return *this;
310 }
311
312
313
314 //! internal function to create the matrix from a textual description
315 template<typename eT>
316 inline
317 void
318 Mat<eT>::init(const std::string& text)
319 {
320 arma_extra_debug_sigprint();
321
322 //
323 // work out the size
324
325 uword t_n_rows = 0;
326 uword t_n_cols = 0;
327
328 bool t_n_cols_found = false;
329
330 std::string token;
331
332 std::string::size_type line_start = 0;
333 std::string::size_type line_end = 0;
334
335 while( line_start < text.length() )
336 {
337
338 line_end = text.find(';', line_start);
339
340 if(line_end == std::string::npos)
341 line_end = text.length()-1;
342
343 std::string::size_type line_len = line_end - line_start + 1;
344 std::stringstream line_stream( text.substr(line_start,line_len) );
345
346
347 uword line_n_cols = 0;
348 while(line_stream >> token)
349 {
350 ++line_n_cols;
351 }
352
353
354 if(line_n_cols > 0)
355 {
356 if(t_n_cols_found == false)
357 {
358 t_n_cols = line_n_cols;
359 t_n_cols_found = true;
360 }
361 else
362 arma_check( (line_n_cols != t_n_cols), "Mat::init(): inconsistent number of columns in given string");
363
364 ++t_n_rows;
365 }
366 line_start = line_end+1;
367
368 }
369
370 Mat<eT>& x = *this;
371 x.set_size(t_n_rows, t_n_cols);
372
373 line_start = 0;
374 line_end = 0;
375
376 uword row = 0;
377
378 while( line_start < text.length() )
379 {
380
381 line_end = text.find(';', line_start);
382
383 if(line_end == std::string::npos)
384 line_end = text.length()-1;
385
386 std::string::size_type line_len = line_end - line_start + 1;
387 std::stringstream line_stream( text.substr(line_start,line_len) );
388
389 // uword col = 0;
390 // while(line_stream >> token)
391 // {
392 // x.at(row,col) = strtod(token.c_str(), 0);
393 // ++col;
394 // }
395
396 uword col = 0;
397 eT val;
398 while(line_stream >> val)
399 {
400 x.at(row,col) = val;
401 ++col;
402 }
403
404 ++row;
405 line_start = line_end+1;
406 }
407
408 }
409
410
411
412 #if defined(ARMA_USE_CXX11)
413
414 template<typename eT>
415 inline
416 Mat<eT>::Mat(const std::initializer_list<eT>& list)
417 : n_rows(0)
418 , n_cols(0)
419 , n_elem(0)
420 , vec_state(0)
421 , mem_state(0)
422 , mem()
423 {
424 arma_extra_debug_sigprint_this(this);
425
426 init(list);
427 }
428
429
430
431 template<typename eT>
432 inline
433 const Mat<eT>&
434 Mat<eT>::operator=(const std::initializer_list<eT>& list)
435 {
436 arma_extra_debug_sigprint();
437
438 init(list);
439
440 return *this;
441 }
442
443 #endif
444
445
446
447 //! Set the matrix to be equal to the specified scalar.
448 //! NOTE: the size of the matrix will be 1x1
449 template<typename eT>
450 arma_inline
451 const Mat<eT>&
452 Mat<eT>::operator=(const eT val)
453 {
454 arma_extra_debug_sigprint();
455
456 init_warm(1,1);
457 access::rw(mem[0]) = val;
458 return *this;
459 }
460
461
462
463 //! In-place addition of a scalar to all elements of the matrix
464 template<typename eT>
465 arma_inline
466 const Mat<eT>&
467 Mat<eT>::operator+=(const eT val)
468 {
469 arma_extra_debug_sigprint();
470
471 arrayops::inplace_plus( memptr(), val, n_elem );
472
473 return *this;
474 }
475
476
477
478 //! In-place subtraction of a scalar from all elements of the matrix
479 template<typename eT>
480 arma_inline
481 const Mat<eT>&
482 Mat<eT>::operator-=(const eT val)
483 {
484 arma_extra_debug_sigprint();
485
486 arrayops::inplace_minus( memptr(), val, n_elem );
487
488 return *this;
489 }
490
491
492
493 //! In-place multiplication of all elements of the matrix with a scalar
494 template<typename eT>
495 arma_inline
496 const Mat<eT>&
497 Mat<eT>::operator*=(const eT val)
498 {
499 arma_extra_debug_sigprint();
500
501 arrayops::inplace_mul( memptr(), val, n_elem );
502
503 return *this;
504 }
505
506
507
508 //! In-place division of all elements of the matrix with a scalar
509 template<typename eT>
510 arma_inline
511 const Mat<eT>&
512 Mat<eT>::operator/=(const eT val)
513 {
514 arma_extra_debug_sigprint();
515
516 arrayops::inplace_div( memptr(), val, n_elem );
517
518 return *this;
519 }
520
521
522
523 //! construct a matrix from a given matrix
524 template<typename eT>
525 inline
526 Mat<eT>::Mat(const Mat<eT>& in_mat)
527 : n_rows(in_mat.n_rows)
528 , n_cols(in_mat.n_cols)
529 , n_elem(in_mat.n_elem)
530 , vec_state(0)
531 , mem_state(0)
532 , mem()
533 {
534 arma_extra_debug_sigprint(arma_boost::format("this = %x in_mat = %x") % this % &in_mat);
535
536 init_cold();
537
538 arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
539 }
540
541
542
543 //! construct a matrix from a given matrix
544 template<typename eT>
545 inline
546 const Mat<eT>&
547 Mat<eT>::operator=(const Mat<eT>& in_mat)
548 {
549 arma_extra_debug_sigprint(arma_boost::format("this = %x in_mat = %x") % this % &in_mat);
550
551 if(this != &in_mat)
552 {
553 init_warm(in_mat.n_rows, in_mat.n_cols);
554
555 arrayops::copy( memptr(), in_mat.mem, in_mat.n_elem );
556 }
557
558 return *this;
559 }
560
561
562
563 #if defined(ARMA_USE_CXX11)
564
565 template<typename eT>
566 inline
567 void
568 Mat<eT>::init(const std::initializer_list<eT>& list)
569 {
570 arma_extra_debug_sigprint();
571
572 const uword N = list.size();
573
574 set_size(1, N);
575
576 arrayops::copy( memptr(), list.begin(), N );
577 }
578
579 #endif
580
581
582
583 //! for constructing a complex matrix out of two non-complex matrices
584 template<typename eT>
585 template<typename T1, typename T2>
586 inline
587 void
588 Mat<eT>::init
589 (
590 const Base<typename Mat<eT>::pod_type, T1>& A,
591 const Base<typename Mat<eT>::pod_type, T2>& B
592 )
593 {
594 arma_extra_debug_sigprint();
595
596 typedef typename T1::elem_type T;
597 typedef typename Proxy<T1>::ea_type ea_type1;
598 typedef typename Proxy<T2>::ea_type ea_type2;
599
600 arma_type_check(( is_complex<eT>::value == false )); //!< compile-time abort if eT isn't std::complex
601 arma_type_check(( is_complex< T>::value == true )); //!< compile-time abort if T is std::complex
602
603 arma_type_check(( is_same_type< std::complex<T>, eT >::value == false )); //!< compile-time abort if types are not compatible
604
605 const Proxy<T1> X(A.get_ref());
606 const Proxy<T2> Y(B.get_ref());
607
608 arma_assert_same_size(X, Y, "Mat()");
609
610 init_warm(X.get_n_rows(), X.get_n_cols());
611
612 const uword N = n_elem;
613 eT* out_mem = memptr();
614 ea_type1 PX = X.get_ea();
615 ea_type2 PY = Y.get_ea();
616
617 for(uword i=0; i<N; ++i)
618 {
619 out_mem[i] = std::complex<T>(PX[i], PY[i]);
620 }
621 }
622
623
624
625 //! try to steal the memory from a given matrix;
626 //! if memory can't be stolen, copy the given matrix
627 template<typename eT>
628 inline
629 void
630 Mat<eT>::steal_mem(Mat<eT>& x)
631 {
632 arma_extra_debug_sigprint();
633
634 if(this != &x)
635 {
636 const uword x_n_rows = x.n_rows;
637 const uword x_n_cols = x.n_cols;
638 const uword x_n_elem = x.n_elem;
639 const uword x_vec_state = x.vec_state;
640 const uword x_mem_state = x.mem_state;
641
642 const uword t_vec_state = vec_state;
643
644 bool layout_ok = false;
645
646 if(t_vec_state == x_vec_state)
647 {
648 layout_ok = true;
649 }
650 else
651 {
652 if( (t_vec_state == 1) && ( x_n_cols == 1) )
653 {
654 layout_ok = true;
655 }
656
657 if( (t_vec_state == 2) && ( x_n_rows == 1) )
658 {
659 layout_ok = true;
660 }
661 }
662
663
664 if( (x_mem_state == 0) && (x_n_elem > arma_config::mat_prealloc) && (layout_ok == true) )
665 {
666 reset();
667 // note: calling reset() also prevents fixed size matrices from changing size or using non-local memory
668
669 access::rw(n_rows) = x_n_rows;
670 access::rw(n_cols) = x_n_cols;
671 access::rw(n_elem) = x_n_elem;
672 access::rw(mem) = x.mem;
673
674 access::rw(x.n_rows) = 0;
675 access::rw(x.n_cols) = 0;
676 access::rw(x.n_elem) = 0;
677 access::rw(x.mem) = 0;
678 }
679 else
680 {
681 (*this).operator=(x);
682 }
683 }
684 }
685
686
687
688 //! construct a matrix from a given auxiliary array of eTs.
689 //! if copy_aux_mem is true, new memory is allocated and the array is copied.
690 //! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
691 //! the default is to copy the array.
692
693 template<typename eT>
694 inline
695 Mat<eT>::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const bool copy_aux_mem, const bool strict)
696 : n_rows ( aux_n_rows )
697 , n_cols ( aux_n_cols )
698 , n_elem ( aux_n_rows*aux_n_cols )
699 , vec_state( 0 )
700 , mem_state( copy_aux_mem ? 0 : ( strict ? 2 : 1 ) )
701 , mem ( copy_aux_mem ? 0 : aux_mem )
702 {
703 arma_extra_debug_sigprint_this(this);
704
705 if(copy_aux_mem == true)
706 {
707 init_cold();
708
709 arrayops::copy( memptr(), aux_mem, n_elem );
710 }
711 }
712
713
714
715 //! construct a matrix from a given auxiliary read-only array of eTs.
716 //! the array is copied.
717 template<typename eT>
718 inline
719 Mat<eT>::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
720 : n_rows(aux_n_rows)
721 , n_cols(aux_n_cols)
722 , n_elem(aux_n_rows*aux_n_cols)
723 , vec_state(0)
724 , mem_state(0)
725 , mem()
726 {
727 arma_extra_debug_sigprint_this(this);
728
729 init_cold();
730
731 arrayops::copy( memptr(), aux_mem, n_elem );
732 }
733
734
735
736 //! DANGEROUS! Construct a temporary matrix, using auxiliary memory.
737 //! This constructor is NOT intended for usage by user code.
738 //! Its sole purpose is to be used by the Cube class.
739
740 template<typename eT>
741 inline
742 Mat<eT>::Mat(const char junk, const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
743 : n_rows (aux_n_rows )
744 , n_cols (aux_n_cols )
745 , n_elem (aux_n_rows*aux_n_cols)
746 , vec_state(0 )
747 , mem_state(3 )
748 , mem (aux_mem )
749 {
750 arma_extra_debug_sigprint_this(this);
751 arma_ignore(junk);
752 }
753
754
755
756 //! in-place matrix addition
757 template<typename eT>
758 inline
759 const Mat<eT>&
760 Mat<eT>::operator+=(const Mat<eT>& m)
761 {
762 arma_extra_debug_sigprint();
763
764 arma_debug_assert_same_size(*this, m, "addition");
765
766 arrayops::inplace_plus( memptr(), m.memptr(), n_elem );
767
768 return *this;
769 }
770
771
772
773 //! in-place matrix subtraction
774 template<typename eT>
775 inline
776 const Mat<eT>&
777 Mat<eT>::operator-=(const Mat<eT>& m)
778 {
779 arma_extra_debug_sigprint();
780
781 arma_debug_assert_same_size(*this, m, "subtraction");
782
783 arrayops::inplace_minus( memptr(), m.memptr(), n_elem );
784
785 return *this;
786 }
787
788
789
790 //! in-place matrix multiplication
791 template<typename eT>
792 inline
793 const Mat<eT>&
794 Mat<eT>::operator*=(const Mat<eT>& m)
795 {
796 arma_extra_debug_sigprint();
797
798 glue_times::apply_inplace(*this, m);
799
800 return *this;
801 }
802
803
804
805 //! in-place element-wise matrix multiplication
806 template<typename eT>
807 inline
808 const Mat<eT>&
809 Mat<eT>::operator%=(const Mat<eT>& m)
810 {
811 arma_extra_debug_sigprint();
812
813 arma_debug_assert_same_size(*this, m, "element-wise multiplication");
814
815 arrayops::inplace_mul( memptr(), m.memptr(), n_elem );
816
817 return *this;
818 }
819
820
821
822 //! in-place element-wise matrix division
823 template<typename eT>
824 inline
825 const Mat<eT>&
826 Mat<eT>::operator/=(const Mat<eT>& m)
827 {
828 arma_extra_debug_sigprint();
829
830 arma_debug_assert_same_size(*this, m, "element-wise division");
831
832 arrayops::inplace_div( memptr(), m.memptr(), n_elem );
833
834 return *this;
835 }
836
837
838
839 template<typename eT>
840 template<typename T1>
841 inline
842 Mat<eT>::Mat(const BaseCube<eT,T1>& X)
843 : n_rows(0)
844 , n_cols(0)
845 , n_elem(0)
846 , vec_state(0)
847 , mem_state(0)
848 , mem()
849 {
850 arma_extra_debug_sigprint_this(this);
851
852 (*this).operator=(X);
853 }
854
855
856
857 template<typename eT>
858 template<typename T1>
859 inline
860 const Mat<eT>&
861 Mat<eT>::operator=(const BaseCube<eT,T1>& X)
862 {
863 arma_extra_debug_sigprint();
864
865 Mat<eT>& out = *this;
866
867 const unwrap_cube<T1> tmp(X.get_ref());
868 const Cube<eT>& in = tmp.M;
869
870 arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false);
871
872 const uword in_n_rows = in.n_rows;
873 const uword in_n_cols = in.n_cols;
874 const uword in_n_slices = in.n_slices;
875
876 const uword out_vec_state = out.vec_state;
877
878 if(in_n_slices == 1)
879 {
880 out.set_size(in_n_rows, in_n_cols);
881
882 for(uword col=0; col < in_n_cols; ++col)
883 {
884 arrayops::copy( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
885 }
886 }
887 else
888 {
889 if(out_vec_state == 0)
890 {
891 if(in_n_cols == 1)
892 {
893 out.set_size(in_n_rows, in_n_slices);
894
895 for(uword i=0; i < in_n_slices; ++i)
896 {
897 arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
898 }
899 }
900 else
901 if(in_n_rows == 1)
902 {
903 out.set_size(in_n_cols, in_n_slices);
904
905 for(uword slice=0; slice < in_n_slices; ++slice)
906 {
907 eT* out_colptr = out.colptr(slice);
908
909 uword i,j;
910 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
911 {
912 const eT tmp_i = in.at(0, i, slice);
913 const eT tmp_j = in.at(0, j, slice);
914
915 out_colptr[i] = tmp_i;
916 out_colptr[j] = tmp_j;
917 }
918
919 if(i < in_n_cols)
920 {
921 out_colptr[i] = in.at(0, i, slice);
922 }
923 }
924 }
925 }
926 else
927 {
928 out.set_size(in_n_slices);
929
930 eT* out_mem = out.memptr();
931
932 for(uword i=0; i<in_n_slices; ++i)
933 {
934 out_mem[i] = in.at(0, 0, i);
935 }
936 }
937 }
938
939 return *this;
940 }
941
942
943
944 template<typename eT>
945 template<typename T1>
946 inline
947 const Mat<eT>&
948 Mat<eT>::operator+=(const BaseCube<eT,T1>& X)
949 {
950 arma_extra_debug_sigprint();
951
952 Mat<eT>& out = *this;
953
954 const unwrap_cube<T1> tmp(X.get_ref());
955 const Cube<eT>& in = tmp.M;
956
957 arma_debug_assert_cube_as_mat(out, in, "addition", true);
958
959 const uword in_n_rows = in.n_rows;
960 const uword in_n_cols = in.n_cols;
961 const uword in_n_slices = in.n_slices;
962
963 const uword out_n_rows = out.n_rows;
964 const uword out_n_cols = out.n_cols;
965 const uword out_vec_state = out.vec_state;
966
967 if(in_n_slices == 1)
968 {
969 for(uword col=0; col < in_n_cols; ++col)
970 {
971 arrayops::inplace_plus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
972 }
973 }
974 else
975 {
976 if(out_vec_state == 0)
977 {
978 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
979 {
980 for(uword i=0; i < in_n_slices; ++i)
981 {
982 arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
983 }
984 }
985 else
986 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
987 {
988 for(uword slice=0; slice < in_n_slices; ++slice)
989 {
990 eT* out_colptr = out.colptr(slice);
991
992 uword i,j;
993 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
994 {
995 const eT tmp_i = in.at(0, i, slice);
996 const eT tmp_j = in.at(0, j, slice);
997
998 out_colptr[i] += tmp_i;
999 out_colptr[j] += tmp_j;
1000 }
1001
1002 if(i < in_n_cols)
1003 {
1004 out_colptr[i] += in.at(0, i, slice);
1005 }
1006 }
1007 }
1008 }
1009 else
1010 {
1011 eT* out_mem = out.memptr();
1012
1013 for(uword i=0; i<in_n_slices; ++i)
1014 {
1015 out_mem[i] += in.at(0, 0, i);
1016 }
1017 }
1018 }
1019
1020 return *this;
1021 }
1022
1023
1024
1025 template<typename eT>
1026 template<typename T1>
1027 inline
1028 const Mat<eT>&
1029 Mat<eT>::operator-=(const BaseCube<eT,T1>& X)
1030 {
1031 arma_extra_debug_sigprint();
1032
1033 Mat<eT>& out = *this;
1034
1035 const unwrap_cube<T1> tmp(X.get_ref());
1036 const Cube<eT>& in = tmp.M;
1037
1038 arma_debug_assert_cube_as_mat(out, in, "subtraction", true);
1039
1040 const uword in_n_rows = in.n_rows;
1041 const uword in_n_cols = in.n_cols;
1042 const uword in_n_slices = in.n_slices;
1043
1044 const uword out_n_rows = out.n_rows;
1045 const uword out_n_cols = out.n_cols;
1046 const uword out_vec_state = out.vec_state;
1047
1048 if(in_n_slices == 1)
1049 {
1050 for(uword col=0; col < in_n_cols; ++col)
1051 {
1052 arrayops::inplace_minus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1053 }
1054 }
1055 else
1056 {
1057 if(out_vec_state == 0)
1058 {
1059 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
1060 {
1061 for(uword i=0; i < in_n_slices; ++i)
1062 {
1063 arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1064 }
1065 }
1066 else
1067 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
1068 {
1069 for(uword slice=0; slice < in_n_slices; ++slice)
1070 {
1071 eT* out_colptr = out.colptr(slice);
1072
1073 uword i,j;
1074 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1075 {
1076 const eT tmp_i = in.at(0, i, slice);
1077 const eT tmp_j = in.at(0, j, slice);
1078
1079 out_colptr[i] -= tmp_i;
1080 out_colptr[j] -= tmp_j;
1081 }
1082
1083 if(i < in_n_cols)
1084 {
1085 out_colptr[i] -= in.at(0, i, slice);
1086 }
1087 }
1088 }
1089 }
1090 else
1091 {
1092 eT* out_mem = out.memptr();
1093
1094 for(uword i=0; i<in_n_slices; ++i)
1095 {
1096 out_mem[i] -= in.at(0, 0, i);
1097 }
1098 }
1099 }
1100
1101 return *this;
1102 }
1103
1104
1105
1106 template<typename eT>
1107 template<typename T1>
1108 inline
1109 const Mat<eT>&
1110 Mat<eT>::operator*=(const BaseCube<eT,T1>& X)
1111 {
1112 arma_extra_debug_sigprint();
1113
1114 const Mat<eT> B(X);
1115
1116 (*this).operator*=(B);
1117
1118 return *this;
1119 }
1120
1121
1122
1123 template<typename eT>
1124 template<typename T1>
1125 inline
1126 const Mat<eT>&
1127 Mat<eT>::operator%=(const BaseCube<eT,T1>& X)
1128 {
1129 arma_extra_debug_sigprint();
1130
1131 Mat<eT>& out = *this;
1132
1133 const unwrap_cube<T1> tmp(X.get_ref());
1134 const Cube<eT>& in = tmp.M;
1135
1136 arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true);
1137
1138 const uword in_n_rows = in.n_rows;
1139 const uword in_n_cols = in.n_cols;
1140 const uword in_n_slices = in.n_slices;
1141
1142 const uword out_n_rows = out.n_rows;
1143 const uword out_n_cols = out.n_cols;
1144 const uword out_vec_state = out.vec_state;
1145
1146 if(in_n_slices == 1)
1147 {
1148 for(uword col=0; col < in_n_cols; ++col)
1149 {
1150 arrayops::inplace_mul( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1151 }
1152 }
1153 else
1154 {
1155 if(out_vec_state == 0)
1156 {
1157 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
1158 {
1159 for(uword i=0; i < in_n_slices; ++i)
1160 {
1161 arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1162 }
1163 }
1164 else
1165 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
1166 {
1167 for(uword slice=0; slice < in_n_slices; ++slice)
1168 {
1169 eT* out_colptr = out.colptr(slice);
1170
1171 uword i,j;
1172 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1173 {
1174 const eT tmp_i = in.at(0, i, slice);
1175 const eT tmp_j = in.at(0, j, slice);
1176
1177 out_colptr[i] *= tmp_i;
1178 out_colptr[j] *= tmp_j;
1179 }
1180
1181 if(i < in_n_cols)
1182 {
1183 out_colptr[i] *= in.at(0, i, slice);
1184 }
1185 }
1186 }
1187 }
1188 else
1189 {
1190 eT* out_mem = out.memptr();
1191
1192 for(uword i=0; i<in_n_slices; ++i)
1193 {
1194 out_mem[i] *= in.at(0, 0, i);
1195 }
1196 }
1197 }
1198
1199 return *this;
1200 }
1201
1202
1203
1204 template<typename eT>
1205 template<typename T1>
1206 inline
1207 const Mat<eT>&
1208 Mat<eT>::operator/=(const BaseCube<eT,T1>& X)
1209 {
1210 arma_extra_debug_sigprint();
1211
1212 Mat<eT>& out = *this;
1213
1214 const unwrap_cube<T1> tmp(X.get_ref());
1215 const Cube<eT>& in = tmp.M;
1216
1217 arma_debug_assert_cube_as_mat(out, in, "element-wise division", true);
1218
1219 const uword in_n_rows = in.n_rows;
1220 const uword in_n_cols = in.n_cols;
1221 const uword in_n_slices = in.n_slices;
1222
1223 const uword out_n_rows = out.n_rows;
1224 const uword out_n_cols = out.n_cols;
1225 const uword out_vec_state = out.vec_state;
1226
1227 if(in_n_slices == 1)
1228 {
1229 for(uword col=0; col < in_n_cols; ++col)
1230 {
1231 arrayops::inplace_div( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1232 }
1233 }
1234 else
1235 {
1236 if(out_vec_state == 0)
1237 {
1238 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
1239 {
1240 for(uword i=0; i < in_n_slices; ++i)
1241 {
1242 arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1243 }
1244 }
1245 else
1246 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
1247 {
1248 for(uword slice=0; slice < in_n_slices; ++slice)
1249 {
1250 eT* out_colptr = out.colptr(slice);
1251
1252 uword i,j;
1253 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1254 {
1255 const eT tmp_i = in.at(0, i, slice);
1256 const eT tmp_j = in.at(0, j, slice);
1257
1258 out_colptr[i] /= tmp_i;
1259 out_colptr[j] /= tmp_j;
1260 }
1261
1262 if(i < in_n_cols)
1263 {
1264 out_colptr[i] /= in.at(0, i, slice);
1265 }
1266 }
1267 }
1268 }
1269 else
1270 {
1271 eT* out_mem = out.memptr();
1272
1273 for(uword i=0; i<in_n_slices; ++i)
1274 {
1275 out_mem[i] /= in.at(0, 0, i);
1276 }
1277 }
1278 }
1279
1280 return *this;
1281 }
1282
1283
1284
1285 //! for constructing a complex matrix out of two non-complex matrices
1286 template<typename eT>
1287 template<typename T1, typename T2>
1288 inline
1289 Mat<eT>::Mat
1290 (
1291 const Base<typename Mat<eT>::pod_type,T1>& A,
1292 const Base<typename Mat<eT>::pod_type,T2>& B
1293 )
1294 : n_rows(0)
1295 , n_cols(0)
1296 , n_elem(0)
1297 , vec_state(0)
1298 , mem_state(0)
1299 , mem()
1300 {
1301 arma_extra_debug_sigprint_this(this);
1302
1303 init(A,B);
1304 }
1305
1306
1307
1308 //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
1309 template<typename eT>
1310 inline
1311 Mat<eT>::Mat(const subview<eT>& X)
1312 : n_rows(X.n_rows)
1313 , n_cols(X.n_cols)
1314 , n_elem(X.n_elem)
1315 , vec_state(0)
1316 , mem_state(0)
1317 , mem()
1318 {
1319 arma_extra_debug_sigprint_this(this);
1320
1321 init_cold();
1322
1323 subview<eT>::extract(*this, X);
1324 }
1325
1326
1327
1328 //! construct a matrix from subview (e.g. construct a matrix from a delayed submatrix operation)
1329 template<typename eT>
1330 inline
1331 const Mat<eT>&
1332 Mat<eT>::operator=(const subview<eT>& X)
1333 {
1334 arma_extra_debug_sigprint();
1335
1336 const bool alias = (this == &(X.m));
1337
1338 if(alias == false)
1339 {
1340 init_warm(X.n_rows, X.n_cols);
1341
1342 subview<eT>::extract(*this, X);
1343 }
1344 else
1345 {
1346 Mat<eT> tmp(X);
1347
1348 steal_mem(tmp);
1349 }
1350
1351 return *this;
1352 }
1353
1354
1355 //! in-place matrix addition (using a submatrix on the right-hand-side)
1356 template<typename eT>
1357 inline
1358 const Mat<eT>&
1359 Mat<eT>::operator+=(const subview<eT>& X)
1360 {
1361 arma_extra_debug_sigprint();
1362
1363 subview<eT>::plus_inplace(*this, X);
1364
1365 return *this;
1366 }
1367
1368
1369 //! in-place matrix subtraction (using a submatrix on the right-hand-side)
1370 template<typename eT>
1371 inline
1372 const Mat<eT>&
1373 Mat<eT>::operator-=(const subview<eT>& X)
1374 {
1375 arma_extra_debug_sigprint();
1376
1377 subview<eT>::minus_inplace(*this, X);
1378
1379 return *this;
1380 }
1381
1382
1383
1384 //! in-place matrix mutiplication (using a submatrix on the right-hand-side)
1385 template<typename eT>
1386 inline
1387 const Mat<eT>&
1388 Mat<eT>::operator*=(const subview<eT>& X)
1389 {
1390 arma_extra_debug_sigprint();
1391
1392 glue_times::apply_inplace(*this, X);
1393
1394 return *this;
1395 }
1396
1397
1398
1399 //! in-place element-wise matrix mutiplication (using a submatrix on the right-hand-side)
1400 template<typename eT>
1401 inline
1402 const Mat<eT>&
1403 Mat<eT>::operator%=(const subview<eT>& X)
1404 {
1405 arma_extra_debug_sigprint();
1406
1407 subview<eT>::schur_inplace(*this, X);
1408
1409 return *this;
1410 }
1411
1412
1413
1414 //! in-place element-wise matrix division (using a submatrix on the right-hand-side)
1415 template<typename eT>
1416 inline
1417 const Mat<eT>&
1418 Mat<eT>::operator/=(const subview<eT>& X)
1419 {
1420 arma_extra_debug_sigprint();
1421
1422 subview<eT>::div_inplace(*this, X);
1423
1424 return *this;
1425 }
1426
1427
1428
1429 //! construct a matrix from a subview_cube instance
1430 template<typename eT>
1431 inline
1432 Mat<eT>::Mat(const subview_cube<eT>& x)
1433 : n_rows(0)
1434 , n_cols(0)
1435 , n_elem(0)
1436 , vec_state(0)
1437 , mem_state(0)
1438 , mem()
1439 {
1440 arma_extra_debug_sigprint_this(this);
1441
1442 this->operator=(x);
1443 }
1444
1445
1446
1447 //! construct a matrix from a subview_cube instance
1448 template<typename eT>
1449 inline
1450 const Mat<eT>&
1451 Mat<eT>::operator=(const subview_cube<eT>& X)
1452 {
1453 arma_extra_debug_sigprint();
1454
1455 subview_cube<eT>::extract(*this, X);
1456
1457 return *this;
1458 }
1459
1460
1461
1462 //! in-place matrix addition (using a single-slice subcube on the right-hand-side)
1463 template<typename eT>
1464 inline
1465 const Mat<eT>&
1466 Mat<eT>::operator+=(const subview_cube<eT>& X)
1467 {
1468 arma_extra_debug_sigprint();
1469
1470 subview_cube<eT>::plus_inplace(*this, X);
1471
1472 return *this;
1473 }
1474
1475
1476
1477 //! in-place matrix subtraction (using a single-slice subcube on the right-hand-side)
1478 template<typename eT>
1479 inline
1480 const Mat<eT>&
1481 Mat<eT>::operator-=(const subview_cube<eT>& X)
1482 {
1483 arma_extra_debug_sigprint();
1484
1485 subview_cube<eT>::minus_inplace(*this, X);
1486
1487 return *this;
1488 }
1489
1490
1491
1492 //! in-place matrix mutiplication (using a single-slice subcube on the right-hand-side)
1493 template<typename eT>
1494 inline
1495 const Mat<eT>&
1496 Mat<eT>::operator*=(const subview_cube<eT>& X)
1497 {
1498 arma_extra_debug_sigprint();
1499
1500 const Mat<eT> tmp(X);
1501 glue_times::apply_inplace(*this, tmp);
1502
1503 return *this;
1504 }
1505
1506
1507
1508 //! in-place element-wise matrix mutiplication (using a single-slice subcube on the right-hand-side)
1509 template<typename eT>
1510 inline
1511 const Mat<eT>&
1512 Mat<eT>::operator%=(const subview_cube<eT>& X)
1513 {
1514 arma_extra_debug_sigprint();
1515
1516 subview_cube<eT>::schur_inplace(*this, X);
1517
1518 return *this;
1519 }
1520
1521
1522
1523 //! in-place element-wise matrix division (using a single-slice subcube on the right-hand-side)
1524 template<typename eT>
1525 inline
1526 const Mat<eT>&
1527 Mat<eT>::operator/=(const subview_cube<eT>& X)
1528 {
1529 arma_extra_debug_sigprint();
1530
1531 subview_cube<eT>::div_inplace(*this, X);
1532
1533 return *this;
1534 }
1535
1536
1537
1538 //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
1539 template<typename eT>
1540 inline
1541 Mat<eT>::Mat(const diagview<eT>& X)
1542 : n_rows(X.n_rows)
1543 , n_cols(X.n_cols)
1544 , n_elem(X.n_elem)
1545 , vec_state(0)
1546 , mem_state(0)
1547 , mem()
1548 {
1549 arma_extra_debug_sigprint_this(this);
1550
1551 init_cold();
1552
1553 diagview<eT>::extract(*this, X);
1554 }
1555
1556
1557
1558 //! construct a matrix from diagview (e.g. construct a matrix from a delayed diag operation)
1559 template<typename eT>
1560 inline
1561 const Mat<eT>&
1562 Mat<eT>::operator=(const diagview<eT>& X)
1563 {
1564 arma_extra_debug_sigprint();
1565
1566 const bool alias = (this == &(X.m));
1567
1568 if(alias == false)
1569 {
1570 init_warm(X.n_rows, X.n_cols);
1571
1572 diagview<eT>::extract(*this, X);
1573 }
1574 else
1575 {
1576 Mat<eT> tmp(X);
1577
1578 steal_mem(tmp);
1579 }
1580
1581 return *this;
1582 }
1583
1584
1585
1586 //! in-place matrix addition (using a diagview on the right-hand-side)
1587 template<typename eT>
1588 inline
1589 const Mat<eT>&
1590 Mat<eT>::operator+=(const diagview<eT>& X)
1591 {
1592 arma_extra_debug_sigprint();
1593
1594 diagview<eT>::plus_inplace(*this, X);
1595
1596 return *this;
1597 }
1598
1599
1600 //! in-place matrix subtraction (using a diagview on the right-hand-side)
1601 template<typename eT>
1602 inline
1603 const Mat<eT>&
1604 Mat<eT>::operator-=(const diagview<eT>& X)
1605 {
1606 arma_extra_debug_sigprint();
1607
1608 diagview<eT>::minus_inplace(*this, X);
1609
1610 return *this;
1611 }
1612
1613
1614
1615 //! in-place matrix mutiplication (using a diagview on the right-hand-side)
1616 template<typename eT>
1617 inline
1618 const Mat<eT>&
1619 Mat<eT>::operator*=(const diagview<eT>& X)
1620 {
1621 arma_extra_debug_sigprint();
1622
1623 glue_times::apply_inplace(*this, X);
1624
1625 return *this;
1626 }
1627
1628
1629
1630 //! in-place element-wise matrix mutiplication (using a diagview on the right-hand-side)
1631 template<typename eT>
1632 inline
1633 const Mat<eT>&
1634 Mat<eT>::operator%=(const diagview<eT>& X)
1635 {
1636 arma_extra_debug_sigprint();
1637
1638 diagview<eT>::schur_inplace(*this, X);
1639
1640 return *this;
1641 }
1642
1643
1644
1645 //! in-place element-wise matrix division (using a diagview on the right-hand-side)
1646 template<typename eT>
1647 inline
1648 const Mat<eT>&
1649 Mat<eT>::operator/=(const diagview<eT>& X)
1650 {
1651 arma_extra_debug_sigprint();
1652
1653 diagview<eT>::div_inplace(*this, X);
1654
1655 return *this;
1656 }
1657
1658
1659
1660 template<typename eT>
1661 template<typename T1>
1662 inline
1663 Mat<eT>::Mat(const subview_elem1<eT,T1>& X)
1664 : n_rows(0)
1665 , n_cols(0)
1666 , n_elem(0)
1667 , vec_state(0)
1668 , mem_state(0)
1669 , mem()
1670 {
1671 arma_extra_debug_sigprint_this(this);
1672
1673 this->operator=(X);
1674 }
1675
1676
1677
1678 template<typename eT>
1679 template<typename T1>
1680 inline
1681 const Mat<eT>&
1682 Mat<eT>::operator=(const subview_elem1<eT,T1>& X)
1683 {
1684 arma_extra_debug_sigprint();
1685
1686 subview_elem1<eT,T1>::extract(*this, X);
1687
1688 return *this;
1689 }
1690
1691
1692
1693 template<typename eT>
1694 template<typename T1>
1695 inline
1696 const Mat<eT>&
1697 Mat<eT>::operator+=(const subview_elem1<eT,T1>& X)
1698 {
1699 arma_extra_debug_sigprint();
1700
1701 subview_elem1<eT,T1>::plus_inplace(*this, X);
1702
1703 return *this;
1704 }
1705
1706
1707
1708 template<typename eT>
1709 template<typename T1>
1710 inline
1711 const Mat<eT>&
1712 Mat<eT>::operator-=(const subview_elem1<eT,T1>& X)
1713 {
1714 arma_extra_debug_sigprint();
1715
1716 subview_elem1<eT,T1>::minus_inplace(*this, X);
1717
1718 return *this;
1719 }
1720
1721
1722
1723 template<typename eT>
1724 template<typename T1>
1725 inline
1726 const Mat<eT>&
1727 Mat<eT>::operator*=(const subview_elem1<eT,T1>& X)
1728 {
1729 arma_extra_debug_sigprint();
1730
1731 glue_times::apply_inplace(*this, X);
1732
1733 return *this;
1734 }
1735
1736
1737
1738 template<typename eT>
1739 template<typename T1>
1740 inline
1741 const Mat<eT>&
1742 Mat<eT>::operator%=(const subview_elem1<eT,T1>& X)
1743 {
1744 arma_extra_debug_sigprint();
1745
1746 subview_elem1<eT,T1>::schur_inplace(*this, X);
1747
1748 return *this;
1749 }
1750
1751
1752
1753 template<typename eT>
1754 template<typename T1>
1755 inline
1756 const Mat<eT>&
1757 Mat<eT>::operator/=(const subview_elem1<eT,T1>& X)
1758 {
1759 arma_extra_debug_sigprint();
1760
1761 subview_elem1<eT,T1>::div_inplace(*this, X);
1762
1763 return *this;
1764 }
1765
1766
1767
1768 template<typename eT>
1769 inline
1770 mat_injector< Mat<eT> >
1771 Mat<eT>::operator<<(const eT val)
1772 {
1773 return mat_injector< Mat<eT> >(*this, val);
1774 }
1775
1776
1777
1778 template<typename eT>
1779 inline
1780 mat_injector< Mat<eT> >
1781 Mat<eT>::operator<<(const injector_end_of_row& x)
1782 {
1783 return mat_injector< Mat<eT> >(*this, x);
1784 }
1785
1786
1787
1788 //! creation of subview (row vector)
1789 template<typename eT>
1790 arma_inline
1791 subview_row<eT>
1792 Mat<eT>::row(const uword row_num)
1793 {
1794 arma_extra_debug_sigprint();
1795
1796 arma_debug_check( row_num >= n_rows, "Mat::row(): out of bounds" );
1797
1798 return subview_row<eT>(*this, row_num);
1799 }
1800
1801
1802
1803 //! creation of subview (row vector)
1804 template<typename eT>
1805 arma_inline
1806 const subview_row<eT>
1807 Mat<eT>::row(const uword row_num) const
1808 {
1809 arma_extra_debug_sigprint();
1810
1811 arma_debug_check( row_num >= n_rows, "Mat::row(): out of bounds" );
1812
1813 return subview_row<eT>(*this, row_num);
1814 }
1815
1816
1817
1818 template<typename eT>
1819 inline
1820 subview_row<eT>
1821 Mat<eT>::operator()(const uword row_num, const span& col_span)
1822 {
1823 arma_extra_debug_sigprint();
1824
1825 const bool col_all = col_span.whole;
1826
1827 const uword local_n_cols = n_cols;
1828
1829 const uword in_col1 = col_all ? 0 : col_span.a;
1830 const uword in_col2 = col_span.b;
1831 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
1832
1833 arma_debug_check
1834 (
1835 (row_num >= n_rows)
1836 ||
1837 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
1838 ,
1839 "Mat::operator(): indices out of bounds or incorrectly used"
1840 );
1841
1842 return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
1843 }
1844
1845
1846
1847 template<typename eT>
1848 inline
1849 const subview_row<eT>
1850 Mat<eT>::operator()(const uword row_num, const span& col_span) const
1851 {
1852 arma_extra_debug_sigprint();
1853
1854 const bool col_all = col_span.whole;
1855
1856 const uword local_n_cols = n_cols;
1857
1858 const uword in_col1 = col_all ? 0 : col_span.a;
1859 const uword in_col2 = col_span.b;
1860 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
1861
1862 arma_debug_check
1863 (
1864 (row_num >= n_rows)
1865 ||
1866 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
1867 ,
1868 "Mat::operator(): indices out of bounds or incorrectly used"
1869 );
1870
1871 return subview_row<eT>(*this, row_num, in_col1, submat_n_cols);
1872 }
1873
1874
1875
1876 //! creation of subview (column vector)
1877 template<typename eT>
1878 arma_inline
1879 subview_col<eT>
1880 Mat<eT>::col(const uword col_num)
1881 {
1882 arma_extra_debug_sigprint();
1883
1884 arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
1885
1886 return subview_col<eT>(*this, col_num);
1887 }
1888
1889
1890
1891 //! creation of subview (column vector)
1892 template<typename eT>
1893 arma_inline
1894 const subview_col<eT>
1895 Mat<eT>::col(const uword col_num) const
1896 {
1897 arma_extra_debug_sigprint();
1898
1899 arma_debug_check( col_num >= n_cols, "Mat::col(): out of bounds");
1900
1901 return subview_col<eT>(*this, col_num);
1902 }
1903
1904
1905
1906 template<typename eT>
1907 inline
1908 subview_col<eT>
1909 Mat<eT>::operator()(const span& row_span, const uword col_num)
1910 {
1911 arma_extra_debug_sigprint();
1912
1913 const bool row_all = row_span.whole;
1914
1915 const uword local_n_rows = n_rows;
1916
1917 const uword in_row1 = row_all ? 0 : row_span.a;
1918 const uword in_row2 = row_span.b;
1919 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
1920
1921 arma_debug_check
1922 (
1923 (col_num >= n_cols)
1924 ||
1925 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
1926 ,
1927 "Mat::operator(): indices out of bounds or incorrectly used"
1928 );
1929
1930 return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
1931 }
1932
1933
1934
1935 template<typename eT>
1936 inline
1937 const subview_col<eT>
1938 Mat<eT>::operator()(const span& row_span, const uword col_num) const
1939 {
1940 arma_extra_debug_sigprint();
1941
1942 const bool row_all = row_span.whole;
1943
1944 const uword local_n_rows = n_rows;
1945
1946 const uword in_row1 = row_all ? 0 : row_span.a;
1947 const uword in_row2 = row_span.b;
1948 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
1949
1950 arma_debug_check
1951 (
1952 (col_num >= n_cols)
1953 ||
1954 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
1955 ,
1956 "Mat::operator(): indices out of bounds or incorrectly used"
1957 );
1958
1959 return subview_col<eT>(*this, col_num, in_row1, submat_n_rows);
1960 }
1961
1962
1963
1964 //! create a Col object which uses memory from an existing matrix object.
1965 //! this approach is currently not alias safe
1966 //! and does not take into account that the parent matrix object could be deleted.
1967 //! if deleted memory is accessed by the created Col object,
1968 //! it will cause memory corruption and/or a crash
1969 template<typename eT>
1970 inline
1971 Col<eT>
1972 Mat<eT>::unsafe_col(const uword col_num)
1973 {
1974 arma_extra_debug_sigprint();
1975
1976 arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): out of bounds");
1977
1978 return Col<eT>(colptr(col_num), n_rows, false, true);
1979 }
1980
1981
1982
1983 //! create a Col object which uses memory from an existing matrix object.
1984 //! this approach is currently not alias safe
1985 //! and does not take into account that the parent matrix object could be deleted.
1986 //! if deleted memory is accessed by the created Col object,
1987 //! it will cause memory corruption and/or a crash
1988 template<typename eT>
1989 inline
1990 const Col<eT>
1991 Mat<eT>::unsafe_col(const uword col_num) const
1992 {
1993 arma_extra_debug_sigprint();
1994
1995 arma_debug_check( col_num >= n_cols, "Mat::unsafe_col(): out of bounds");
1996
1997 typedef const Col<eT> out_type;
1998
1999 return out_type(const_cast<eT*>(colptr(col_num)), n_rows, false, true);
2000 }
2001
2002
2003
2004 //! creation of subview (submatrix comprised of specified row vectors)
2005 template<typename eT>
2006 arma_inline
2007 subview<eT>
2008 Mat<eT>::rows(const uword in_row1, const uword in_row2)
2009 {
2010 arma_extra_debug_sigprint();
2011
2012 arma_debug_check
2013 (
2014 (in_row1 > in_row2) || (in_row2 >= n_rows),
2015 "Mat::rows(): indices out of bounds or incorrectly used"
2016 );
2017
2018 const uword subview_n_rows = in_row2 - in_row1 + 1;
2019
2020 return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
2021 }
2022
2023
2024
2025 //! creation of subview (submatrix comprised of specified row vectors)
2026 template<typename eT>
2027 arma_inline
2028 const subview<eT>
2029 Mat<eT>::rows(const uword in_row1, const uword in_row2) const
2030 {
2031 arma_extra_debug_sigprint();
2032
2033 arma_debug_check
2034 (
2035 (in_row1 > in_row2) || (in_row2 >= n_rows),
2036 "Mat::rows(): indices out of bounds or incorrectly used"
2037 );
2038
2039 const uword subview_n_rows = in_row2 - in_row1 + 1;
2040
2041 return subview<eT>(*this, in_row1, 0, subview_n_rows, n_cols );
2042 }
2043
2044
2045
2046 //! creation of subview (submatrix comprised of specified column vectors)
2047 template<typename eT>
2048 arma_inline
2049 subview<eT>
2050 Mat<eT>::cols(const uword in_col1, const uword in_col2)
2051 {
2052 arma_extra_debug_sigprint();
2053
2054 arma_debug_check
2055 (
2056 (in_col1 > in_col2) || (in_col2 >= n_cols),
2057 "Mat::cols(): indices out of bounds or incorrectly used"
2058 );
2059
2060 const uword subview_n_cols = in_col2 - in_col1 + 1;
2061
2062 return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
2063 }
2064
2065
2066
2067 //! creation of subview (submatrix comprised of specified column vectors)
2068 template<typename eT>
2069 arma_inline
2070 const subview<eT>
2071 Mat<eT>::cols(const uword in_col1, const uword in_col2) const
2072 {
2073 arma_extra_debug_sigprint();
2074
2075 arma_debug_check
2076 (
2077 (in_col1 > in_col2) || (in_col2 >= n_cols),
2078 "Mat::cols(): indices out of bounds or incorrectly used"
2079 );
2080
2081 const uword subview_n_cols = in_col2 - in_col1 + 1;
2082
2083 return subview<eT>(*this, 0, in_col1, n_rows, subview_n_cols);
2084 }
2085
2086
2087
2088 //! creation of subview (submatrix)
2089 template<typename eT>
2090 arma_inline
2091 subview<eT>
2092 Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
2093 {
2094 arma_extra_debug_sigprint();
2095
2096 arma_debug_check
2097 (
2098 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
2099 "Mat::submat(): indices out of bounds or incorrectly used"
2100 );
2101
2102 const uword subview_n_rows = in_row2 - in_row1 + 1;
2103 const uword subview_n_cols = in_col2 - in_col1 + 1;
2104
2105 return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
2106 }
2107
2108
2109
2110 //! creation of subview (generic submatrix)
2111 template<typename eT>
2112 arma_inline
2113 const subview<eT>
2114 Mat<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
2115 {
2116 arma_extra_debug_sigprint();
2117
2118 arma_debug_check
2119 (
2120 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
2121 "Mat::submat(): indices out of bounds or incorrectly used"
2122 );
2123
2124 const uword subview_n_rows = in_row2 - in_row1 + 1;
2125 const uword subview_n_cols = in_col2 - in_col1 + 1;
2126
2127 return subview<eT>(*this, in_row1, in_col1, subview_n_rows, subview_n_cols);
2128 }
2129
2130
2131
2132 //! creation of subview (submatrix)
2133 template<typename eT>
2134 inline
2135 subview<eT>
2136 Mat<eT>::submat(const span& row_span, const span& col_span)
2137 {
2138 arma_extra_debug_sigprint();
2139
2140 const bool row_all = row_span.whole;
2141 const bool col_all = col_span.whole;
2142
2143 const uword local_n_rows = n_rows;
2144 const uword local_n_cols = n_cols;
2145
2146 const uword in_row1 = row_all ? 0 : row_span.a;
2147 const uword in_row2 = row_span.b;
2148 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
2149
2150 const uword in_col1 = col_all ? 0 : col_span.a;
2151 const uword in_col2 = col_span.b;
2152 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
2153
2154 arma_debug_check
2155 (
2156 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
2157 ||
2158 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
2159 ,
2160 "Mat::submat(): indices out of bounds or incorrectly used"
2161 );
2162
2163 return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
2164 }
2165
2166
2167
2168 //! creation of subview (generic submatrix)
2169 template<typename eT>
2170 inline
2171 const subview<eT>
2172 Mat<eT>::submat(const span& row_span, const span& col_span) const
2173 {
2174 arma_extra_debug_sigprint();
2175
2176 const bool row_all = row_span.whole;
2177 const bool col_all = col_span.whole;
2178
2179 const uword local_n_rows = n_rows;
2180 const uword local_n_cols = n_cols;
2181
2182 const uword in_row1 = row_all ? 0 : row_span.a;
2183 const uword in_row2 = row_span.b;
2184 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
2185
2186 const uword in_col1 = col_all ? 0 : col_span.a;
2187 const uword in_col2 = col_span.b;
2188 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
2189
2190 arma_debug_check
2191 (
2192 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
2193 ||
2194 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
2195 ,
2196 "Mat::submat(): indices out of bounds or incorrectly used"
2197 );
2198
2199 return subview<eT>(*this, in_row1, in_col1, submat_n_rows, submat_n_cols);
2200 }
2201
2202
2203
2204 template<typename eT>
2205 inline
2206 subview<eT>
2207 Mat<eT>::operator()(const span& row_span, const span& col_span)
2208 {
2209 arma_extra_debug_sigprint();
2210
2211 return (*this).submat(row_span, col_span);
2212 }
2213
2214
2215
2216 template<typename eT>
2217 inline
2218 const subview<eT>
2219 Mat<eT>::operator()(const span& row_span, const span& col_span) const
2220 {
2221 arma_extra_debug_sigprint();
2222
2223 return (*this).submat(row_span, col_span);
2224 }
2225
2226
2227
2228 template<typename eT>
2229 template<typename T1>
2230 arma_inline
2231 subview_elem1<eT,T1>
2232 Mat<eT>::elem(const Base<uword,T1>& a)
2233 {
2234 arma_extra_debug_sigprint();
2235
2236 return subview_elem1<eT,T1>(*this, a);
2237 }
2238
2239
2240
2241 template<typename eT>
2242 template<typename T1>
2243 arma_inline
2244 const subview_elem1<eT,T1>
2245 Mat<eT>::elem(const Base<uword,T1>& a) const
2246 {
2247 arma_extra_debug_sigprint();
2248
2249 return subview_elem1<eT,T1>(*this, a);
2250 }
2251
2252
2253
2254 // template<typename eT>
2255 // template<typename T1, typename T2>
2256 // arma_inline
2257 // subview_elem2<eT,T1,T2>
2258 // Mat<eT>::elem(const Base<uword,T1>& a, const Base<uword,T2>& b)
2259 // {
2260 // arma_extra_debug_sigprint();
2261 //
2262 // return subview_elem2<eT,T1,T2>(*this, a, b);
2263 // }
2264 //
2265 //
2266 //
2267 // template<typename eT>
2268 // template<typename T1, typename T2>
2269 // arma_inline
2270 // const subview_elem2<eT,T1,T2>
2271 // Mat<eT>::elem(const Base<uword,T1>& a, const Base<uword,T2>& b) const
2272 // {
2273 // arma_extra_debug_sigprint();
2274 //
2275 // return subview_elem2<eT,T1,T2>(*this, a, b);
2276 // }
2277
2278
2279
2280 //! creation of diagview (diagonal)
2281 template<typename eT>
2282 arma_inline
2283 diagview<eT>
2284 Mat<eT>::diag(const sword in_id)
2285 {
2286 arma_extra_debug_sigprint();
2287
2288 const uword row_offset = (in_id < 0) ? uword(-in_id) : 0;
2289 const uword col_offset = (in_id > 0) ? uword( in_id) : 0;
2290
2291 arma_debug_check
2292 (
2293 ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
2294 "Mat::diag(): requested diagonal out of bounds"
2295 );
2296
2297 const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
2298
2299 return diagview<eT>(*this, row_offset, col_offset, len);
2300 }
2301
2302
2303
2304 //! creation of diagview (diagonal)
2305 template<typename eT>
2306 arma_inline
2307 const diagview<eT>
2308 Mat<eT>::diag(const sword in_id) const
2309 {
2310 arma_extra_debug_sigprint();
2311
2312 const uword row_offset = (in_id < 0) ? -in_id : 0;
2313 const uword col_offset = (in_id > 0) ? in_id : 0;
2314
2315 arma_debug_check
2316 (
2317 ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
2318 "Mat::diag(): requested diagonal out of bounds"
2319 );
2320
2321 const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
2322
2323 return diagview<eT>(*this, row_offset, col_offset, len);
2324 }
2325
2326
2327
2328 template<typename eT>
2329 inline
2330 void
2331 Mat<eT>::swap_rows(const uword in_row1, const uword in_row2)
2332 {
2333 arma_extra_debug_sigprint();
2334
2335 arma_debug_check
2336 (
2337 (in_row1 >= n_rows) || (in_row2 >= n_rows),
2338 "Mat::swap_rows(): out of bounds"
2339 );
2340
2341 for(uword col=0; col<n_cols; ++col)
2342 {
2343 const uword offset = col*n_rows;
2344 const uword pos1 = in_row1 + offset;
2345 const uword pos2 = in_row2 + offset;
2346
2347 const eT tmp = mem[pos1];
2348 access::rw(mem[pos1]) = mem[pos2];
2349 access::rw(mem[pos2]) = tmp;
2350 }
2351
2352 }
2353
2354
2355
2356 template<typename eT>
2357 inline
2358 void
2359 Mat<eT>::swap_cols(const uword in_col1, const uword in_col2)
2360 {
2361 arma_extra_debug_sigprint();
2362
2363 arma_debug_check
2364 (
2365 (in_col1 >= n_cols) || (in_col2 >= n_cols),
2366 "Mat::swap_cols(): out of bounds"
2367 );
2368
2369 if(n_elem > 0)
2370 {
2371 eT* ptr1 = colptr(in_col1);
2372 eT* ptr2 = colptr(in_col2);
2373
2374 for(uword row=0; row<n_rows; ++row)
2375 {
2376 const eT tmp = ptr1[row];
2377 ptr1[row] = ptr2[row];
2378 ptr2[row] = tmp;
2379 }
2380 }
2381 }
2382
2383
2384
2385 //! remove specified row
2386 template<typename eT>
2387 inline
2388 void
2389 Mat<eT>::shed_row(const uword row_num)
2390 {
2391 arma_extra_debug_sigprint();
2392
2393 arma_debug_check( row_num >= n_rows, "Mat::shed_row(): out of bounds");
2394
2395 shed_rows(row_num, row_num);
2396 }
2397
2398
2399
2400 //! remove specified column
2401 template<typename eT>
2402 inline
2403 void
2404 Mat<eT>::shed_col(const uword col_num)
2405 {
2406 arma_extra_debug_sigprint();
2407
2408 arma_debug_check( col_num >= n_cols, "Mat::shed_col(): out of bounds");
2409
2410 shed_cols(col_num, col_num);
2411 }
2412
2413
2414
2415 //! remove specified rows
2416 template<typename eT>
2417 inline
2418 void
2419 Mat<eT>::shed_rows(const uword in_row1, const uword in_row2)
2420 {
2421 arma_extra_debug_sigprint();
2422
2423 arma_debug_check
2424 (
2425 (in_row1 > in_row2) || (in_row2 >= n_rows),
2426 "Mat::shed_rows(): indices out of bounds or incorrectly used"
2427 );
2428
2429 const uword n_keep_front = in_row1;
2430 const uword n_keep_back = n_rows - (in_row2 + 1);
2431
2432 Mat<eT> X(n_keep_front + n_keep_back, n_cols);
2433
2434 if(n_keep_front > 0)
2435 {
2436 X.rows( 0, (n_keep_front-1) ) = rows( 0, (in_row1-1) );
2437 }
2438
2439 if(n_keep_back > 0)
2440 {
2441 X.rows( n_keep_front, (n_keep_front+n_keep_back-1) ) = rows( (in_row2+1), (n_rows-1) );
2442 }
2443
2444 steal_mem(X);
2445 }
2446
2447
2448
2449 //! remove specified columns
2450 template<typename eT>
2451 inline
2452 void
2453 Mat<eT>::shed_cols(const uword in_col1, const uword in_col2)
2454 {
2455 arma_extra_debug_sigprint();
2456
2457 arma_debug_check
2458 (
2459 (in_col1 > in_col2) || (in_col2 >= n_cols),
2460 "Mat::shed_cols(): indices out of bounds or incorrectly used"
2461 );
2462
2463 const uword n_keep_front = in_col1;
2464 const uword n_keep_back = n_cols - (in_col2 + 1);
2465
2466 Mat<eT> X(n_rows, n_keep_front + n_keep_back);
2467
2468 if(n_keep_front > 0)
2469 {
2470 X.cols( 0, (n_keep_front-1) ) = cols( 0, (in_col1-1) );
2471 }
2472
2473 if(n_keep_back > 0)
2474 {
2475 X.cols( n_keep_front, (n_keep_front+n_keep_back-1) ) = cols( (in_col2+1), (n_cols-1) );
2476 }
2477
2478 steal_mem(X);
2479 }
2480
2481
2482
2483 //! insert N rows at the specified row position,
2484 //! optionally setting the elements of the inserted rows to zero
2485 template<typename eT>
2486 inline
2487 void
2488 Mat<eT>::insert_rows(const uword row_num, const uword N, const bool set_to_zero)
2489 {
2490 arma_extra_debug_sigprint();
2491
2492 const uword t_n_rows = n_rows;
2493 const uword t_n_cols = n_cols;
2494
2495 const uword A_n_rows = row_num;
2496 const uword B_n_rows = t_n_rows - row_num;
2497
2498 // insertion at row_num == n_rows is in effect an append operation
2499 arma_debug_check( (row_num > t_n_rows), "Mat::insert_rows(): out of bounds");
2500
2501 if(N > 0)
2502 {
2503 Mat<eT> out(t_n_rows + N, t_n_cols);
2504
2505 if(A_n_rows > 0)
2506 {
2507 out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
2508 }
2509
2510 if(B_n_rows > 0)
2511 {
2512 out.rows(row_num + N, t_n_rows + N - 1) = rows(row_num, t_n_rows-1);
2513 }
2514
2515 if(set_to_zero == true)
2516 {
2517 out.rows(row_num, row_num + N - 1).zeros();
2518 }
2519
2520 steal_mem(out);
2521 }
2522 }
2523
2524
2525
2526 //! insert N columns at the specified column position,
2527 //! optionally setting the elements of the inserted columns to zero
2528 template<typename eT>
2529 inline
2530 void
2531 Mat<eT>::insert_cols(const uword col_num, const uword N, const bool set_to_zero)
2532 {
2533 arma_extra_debug_sigprint();
2534
2535 const uword t_n_rows = n_rows;
2536 const uword t_n_cols = n_cols;
2537
2538 const uword A_n_cols = col_num;
2539 const uword B_n_cols = t_n_cols - col_num;
2540
2541 // insertion at col_num == n_cols is in effect an append operation
2542 arma_debug_check( (col_num > t_n_cols), "Mat::insert_cols(): out of bounds");
2543
2544 if(N > 0)
2545 {
2546 Mat<eT> out(t_n_rows, t_n_cols + N);
2547
2548 if(A_n_cols > 0)
2549 {
2550 out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
2551 }
2552
2553 if(B_n_cols > 0)
2554 {
2555 out.cols(col_num + N, t_n_cols + N - 1) = cols(col_num, t_n_cols-1);
2556 }
2557
2558 if(set_to_zero == true)
2559 {
2560 out.cols(col_num, col_num + N - 1).zeros();
2561 }
2562
2563 steal_mem(out);
2564 }
2565 }
2566
2567
2568
2569 //! insert the given object at the specified row position;
2570 //! the given object must have the same number of columns as the matrix
2571 template<typename eT>
2572 template<typename T1>
2573 inline
2574 void
2575 Mat<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
2576 {
2577 arma_extra_debug_sigprint();
2578
2579 const unwrap<T1> tmp(X.get_ref());
2580 const Mat<eT>& C = tmp.M;
2581
2582 const uword C_n_rows = C.n_rows;
2583 const uword C_n_cols = C.n_cols;
2584
2585 const uword t_n_rows = n_rows;
2586 const uword t_n_cols = n_cols;
2587
2588 const uword A_n_rows = row_num;
2589 const uword B_n_rows = t_n_rows - row_num;
2590
2591 bool err_state = false;
2592 char* err_msg = 0;
2593
2594 // insertion at row_num == n_rows is in effect an append operation
2595
2596 arma_debug_set_error
2597 (
2598 err_state,
2599 err_msg,
2600 (row_num > t_n_rows),
2601 "Mat::insert_rows(): out of bounds"
2602 );
2603
2604 arma_debug_set_error
2605 (
2606 err_state,
2607 err_msg,
2608 ( (C_n_cols != t_n_cols) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
2609 "Mat::insert_rows(): given object has an incompatible number of columns"
2610 );
2611
2612 arma_debug_check(err_state, err_msg);
2613
2614 if(C_n_rows > 0)
2615 {
2616 Mat<eT> out( t_n_rows + C_n_rows, (std::max)(t_n_cols, C_n_cols) );
2617
2618 if(t_n_cols > 0)
2619 {
2620 if(A_n_rows > 0)
2621 {
2622 out.rows(0, A_n_rows-1) = rows(0, A_n_rows-1);
2623 }
2624
2625 if( (t_n_cols > 0) && (B_n_rows > 0) )
2626 {
2627 out.rows(row_num + C_n_rows, t_n_rows + C_n_rows - 1) = rows(row_num, t_n_rows - 1);
2628 }
2629 }
2630
2631 if(C_n_cols > 0)
2632 {
2633 out.rows(row_num, row_num + C_n_rows - 1) = C;
2634 }
2635
2636 steal_mem(out);
2637 }
2638 }
2639
2640
2641
2642 //! insert the given object at the specified column position;
2643 //! the given object must have the same number of rows as the matrix
2644 template<typename eT>
2645 template<typename T1>
2646 inline
2647 void
2648 Mat<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
2649 {
2650 arma_extra_debug_sigprint();
2651
2652 const unwrap<T1> tmp(X.get_ref());
2653 const Mat<eT>& C = tmp.M;
2654
2655 const uword C_n_rows = C.n_rows;
2656 const uword C_n_cols = C.n_cols;
2657
2658 const uword t_n_rows = n_rows;
2659 const uword t_n_cols = n_cols;
2660
2661 const uword A_n_cols = col_num;
2662 const uword B_n_cols = t_n_cols - col_num;
2663
2664 bool err_state = false;
2665 char* err_msg = 0;
2666
2667 // insertion at col_num == n_cols is in effect an append operation
2668
2669 arma_debug_set_error
2670 (
2671 err_state,
2672 err_msg,
2673 (col_num > t_n_cols),
2674 "Mat::insert_cols(): out of bounds"
2675 );
2676
2677 arma_debug_set_error
2678 (
2679 err_state,
2680 err_msg,
2681 ( (C_n_rows != t_n_rows) && ( (t_n_rows > 0) || (t_n_cols > 0) ) && ( (C_n_rows > 0) || (C_n_cols > 0) ) ),
2682 "Mat::insert_cols(): given object has an incompatible number of rows"
2683 );
2684
2685 arma_debug_check(err_state, err_msg);
2686
2687 if(C_n_cols > 0)
2688 {
2689 Mat<eT> out( (std::max)(t_n_rows, C_n_rows), t_n_cols + C_n_cols );
2690
2691 if(t_n_rows > 0)
2692 {
2693 if(A_n_cols > 0)
2694 {
2695 out.cols(0, A_n_cols-1) = cols(0, A_n_cols-1);
2696 }
2697
2698 if(B_n_cols > 0)
2699 {
2700 out.cols(col_num + C_n_cols, t_n_cols + C_n_cols - 1) = cols(col_num, t_n_cols - 1);
2701 }
2702 }
2703
2704 if(C_n_rows > 0)
2705 {
2706 out.cols(col_num, col_num + C_n_cols - 1) = C;
2707 }
2708
2709 steal_mem(out);
2710 }
2711 }
2712
2713
2714
2715 template<typename eT>
2716 template<typename gen_type>
2717 inline
2718 Mat<eT>::Mat(const Gen<eT, gen_type>& X)
2719 : n_rows(X.n_rows)
2720 , n_cols(X.n_cols)
2721 , n_elem(n_rows*n_cols)
2722 , vec_state(0)
2723 , mem_state(0)
2724 , mem()
2725 {
2726 arma_extra_debug_sigprint_this(this);
2727
2728 init_cold();
2729
2730 X.apply(*this);
2731 }
2732
2733
2734
2735 template<typename eT>
2736 template<typename gen_type>
2737 inline
2738 const Mat<eT>&
2739 Mat<eT>::operator=(const Gen<eT, gen_type>& X)
2740 {
2741 arma_extra_debug_sigprint();
2742
2743 init_warm(X.n_rows, X.n_cols);
2744
2745 X.apply(*this);
2746
2747 return *this;
2748 }
2749
2750
2751
2752 template<typename eT>
2753 template<typename gen_type>
2754 inline
2755 const Mat<eT>&
2756 Mat<eT>::operator+=(const Gen<eT, gen_type>& X)
2757 {
2758 arma_extra_debug_sigprint();
2759
2760 X.apply_inplace_plus(*this);
2761
2762 return *this;
2763 }
2764
2765
2766
2767 template<typename eT>
2768 template<typename gen_type>
2769 inline
2770 const Mat<eT>&
2771 Mat<eT>::operator-=(const Gen<eT, gen_type>& X)
2772 {
2773 arma_extra_debug_sigprint();
2774
2775 X.apply_inplace_minus(*this);
2776
2777 return *this;
2778 }
2779
2780
2781
2782 template<typename eT>
2783 template<typename gen_type>
2784 inline
2785 const Mat<eT>&
2786 Mat<eT>::operator*=(const Gen<eT, gen_type>& X)
2787 {
2788 arma_extra_debug_sigprint();
2789
2790 const Mat<eT> tmp(X);
2791
2792 return (*this).operator*=(tmp);
2793 }
2794
2795
2796
2797 template<typename eT>
2798 template<typename gen_type>
2799 inline
2800 const Mat<eT>&
2801 Mat<eT>::operator%=(const Gen<eT, gen_type>& X)
2802 {
2803 arma_extra_debug_sigprint();
2804
2805 X.apply_inplace_schur(*this);
2806
2807 return *this;
2808 }
2809
2810
2811
2812 template<typename eT>
2813 template<typename gen_type>
2814 inline
2815 const Mat<eT>&
2816 Mat<eT>::operator/=(const Gen<eT, gen_type>& X)
2817 {
2818 arma_extra_debug_sigprint();
2819
2820 X.apply_inplace_div(*this);
2821
2822 return *this;
2823 }
2824
2825
2826
2827 //! create a matrix from Op, i.e. run the previously delayed unary operations
2828 template<typename eT>
2829 template<typename T1, typename op_type>
2830 inline
2831 Mat<eT>::Mat(const Op<T1, op_type>& X)
2832 : n_rows(0)
2833 , n_cols(0)
2834 , n_elem(0)
2835 , vec_state(0)
2836 , mem_state(0)
2837 , mem()
2838 {
2839 arma_extra_debug_sigprint_this(this);
2840
2841 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2842
2843 op_type::apply(*this, X);
2844 }
2845
2846
2847
2848 //! create a matrix from Op, i.e. run the previously delayed unary operations
2849 template<typename eT>
2850 template<typename T1, typename op_type>
2851 inline
2852 const Mat<eT>&
2853 Mat<eT>::operator=(const Op<T1, op_type>& X)
2854 {
2855 arma_extra_debug_sigprint();
2856
2857 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2858
2859 op_type::apply(*this, X);
2860
2861 return *this;
2862 }
2863
2864
2865
2866 //! in-place matrix addition, with the right-hand-side operand having delayed operations
2867 template<typename eT>
2868 template<typename T1, typename op_type>
2869 inline
2870 const Mat<eT>&
2871 Mat<eT>::operator+=(const Op<T1, op_type>& X)
2872 {
2873 arma_extra_debug_sigprint();
2874
2875 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2876
2877 const Mat<eT> m(X);
2878
2879 return (*this).operator+=(m);
2880 }
2881
2882
2883
2884 //! in-place matrix subtraction, with the right-hand-side operand having delayed operations
2885 template<typename eT>
2886 template<typename T1, typename op_type>
2887 inline
2888 const Mat<eT>&
2889 Mat<eT>::operator-=(const Op<T1, op_type>& X)
2890 {
2891 arma_extra_debug_sigprint();
2892
2893 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2894
2895 const Mat<eT> m(X);
2896
2897 return (*this).operator-=(m);
2898 }
2899
2900
2901
2902 //! in-place matrix multiplication, with the right-hand-side operand having delayed operations
2903 template<typename eT>
2904 template<typename T1, typename op_type>
2905 inline
2906 const Mat<eT>&
2907 Mat<eT>::operator*=(const Op<T1, op_type>& X)
2908 {
2909 arma_extra_debug_sigprint();
2910
2911 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2912
2913 glue_times::apply_inplace(*this, X);
2914
2915 return *this;
2916 }
2917
2918
2919
2920 //! in-place matrix element-wise multiplication, with the right-hand-side operand having delayed operations
2921 template<typename eT>
2922 template<typename T1, typename op_type>
2923 inline
2924 const Mat<eT>&
2925 Mat<eT>::operator%=(const Op<T1, op_type>& X)
2926 {
2927 arma_extra_debug_sigprint();
2928
2929 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2930
2931 const Mat<eT> m(X);
2932
2933 return (*this).operator%=(m);
2934 }
2935
2936
2937
2938 //! in-place matrix element-wise division, with the right-hand-side operand having delayed operations
2939 template<typename eT>
2940 template<typename T1, typename op_type>
2941 inline
2942 const Mat<eT>&
2943 Mat<eT>::operator/=(const Op<T1, op_type>& X)
2944 {
2945 arma_extra_debug_sigprint();
2946
2947 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2948
2949 const Mat<eT> m(X);
2950
2951 return (*this).operator/=(m);
2952 }
2953
2954
2955
2956 //! create a matrix from eOp, i.e. run the previously delayed unary operations
2957 template<typename eT>
2958 template<typename T1, typename eop_type>
2959 inline
2960 Mat<eT>::Mat(const eOp<T1, eop_type>& X)
2961 : n_rows(X.get_n_rows())
2962 , n_cols(X.get_n_cols())
2963 , n_elem(X.get_n_elem())
2964 , vec_state(0)
2965 , mem_state(0)
2966 , mem()
2967 {
2968 arma_extra_debug_sigprint_this(this);
2969
2970 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2971
2972 init_cold();
2973
2974 eop_type::apply(*this, X);
2975 }
2976
2977
2978
2979 //! create a matrix from eOp, i.e. run the previously delayed unary operations
2980 template<typename eT>
2981 template<typename T1, typename eop_type>
2982 inline
2983 const Mat<eT>&
2984 Mat<eT>::operator=(const eOp<T1, eop_type>& X)
2985 {
2986 arma_extra_debug_sigprint();
2987
2988 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
2989
2990 const bool bad_alias = (X.P.has_subview && X.P.is_alias(*this));
2991
2992 if(bad_alias == false)
2993 {
2994 init_warm(X.get_n_rows(), X.get_n_cols());
2995
2996 eop_type::apply(*this, X);
2997 }
2998 else
2999 {
3000 Mat<eT> tmp(X);
3001
3002 steal_mem(tmp);
3003 }
3004
3005 return *this;
3006 }
3007
3008
3009
3010 template<typename eT>
3011 template<typename T1, typename eop_type>
3012 inline
3013 const Mat<eT>&
3014 Mat<eT>::operator+=(const eOp<T1, eop_type>& X)
3015 {
3016 arma_extra_debug_sigprint();
3017
3018 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3019
3020 eop_type::apply_inplace_plus(*this, X);
3021
3022 return *this;
3023 }
3024
3025
3026
3027 template<typename eT>
3028 template<typename T1, typename eop_type>
3029 inline
3030 const Mat<eT>&
3031 Mat<eT>::operator-=(const eOp<T1, eop_type>& X)
3032 {
3033 arma_extra_debug_sigprint();
3034
3035 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3036
3037 eop_type::apply_inplace_minus(*this, X);
3038
3039 return *this;
3040 }
3041
3042
3043
3044 template<typename eT>
3045 template<typename T1, typename eop_type>
3046 inline
3047 const Mat<eT>&
3048 Mat<eT>::operator*=(const eOp<T1, eop_type>& X)
3049 {
3050 arma_extra_debug_sigprint();
3051
3052 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3053
3054 glue_times::apply_inplace(*this, X);
3055
3056 return *this;
3057 }
3058
3059
3060
3061 template<typename eT>
3062 template<typename T1, typename eop_type>
3063 inline
3064 const Mat<eT>&
3065 Mat<eT>::operator%=(const eOp<T1, eop_type>& X)
3066 {
3067 arma_extra_debug_sigprint();
3068
3069 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3070
3071 eop_type::apply_inplace_schur(*this, X);
3072
3073 return *this;
3074 }
3075
3076
3077
3078 template<typename eT>
3079 template<typename T1, typename eop_type>
3080 inline
3081 const Mat<eT>&
3082 Mat<eT>::operator/=(const eOp<T1, eop_type>& X)
3083 {
3084 arma_extra_debug_sigprint();
3085
3086 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3087
3088 eop_type::apply_inplace_div(*this, X);
3089
3090 return *this;
3091 }
3092
3093
3094
3095 //! EXPERIMENTAL
3096 template<typename eT>
3097 template<typename T1, typename op_type>
3098 inline
3099 Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X)
3100 : n_rows(0)
3101 , n_cols(0)
3102 , n_elem(0)
3103 , vec_state(0)
3104 , mem_state(0)
3105 , mem()
3106 {
3107 arma_extra_debug_sigprint_this(this);
3108
3109 op_type::apply(*this, X);
3110 }
3111
3112
3113
3114 //! EXPERIMENTAL
3115 template<typename eT>
3116 template<typename T1, typename op_type>
3117 inline
3118 const Mat<eT>&
3119 Mat<eT>::operator=(const mtOp<eT, T1, op_type>& X)
3120 {
3121 arma_extra_debug_sigprint();
3122
3123 op_type::apply(*this, X);
3124
3125 return *this;
3126 }
3127
3128
3129
3130 //! EXPERIMENTAL
3131 template<typename eT>
3132 template<typename T1, typename op_type>
3133 inline
3134 const Mat<eT>&
3135 Mat<eT>::operator+=(const mtOp<eT, T1, op_type>& X)
3136 {
3137 arma_extra_debug_sigprint();
3138
3139 const Mat<eT> m(X);
3140
3141 return (*this).operator+=(m);
3142 }
3143
3144
3145
3146 //! EXPERIMENTAL
3147 template<typename eT>
3148 template<typename T1, typename op_type>
3149 inline
3150 const Mat<eT>&
3151 Mat<eT>::operator-=(const mtOp<eT, T1, op_type>& X)
3152 {
3153 arma_extra_debug_sigprint();
3154
3155 const Mat<eT> m(X);
3156
3157 return (*this).operator-=(m);
3158 }
3159
3160
3161
3162 //! EXPERIMENTAL
3163 template<typename eT>
3164 template<typename T1, typename op_type>
3165 inline
3166 const Mat<eT>&
3167 Mat<eT>::operator*=(const mtOp<eT, T1, op_type>& X)
3168 {
3169 arma_extra_debug_sigprint();
3170
3171 const Mat<eT> m(X);
3172
3173 return (*this).operator*=(m);
3174 }
3175
3176
3177
3178 //! EXPERIMENTAL
3179 template<typename eT>
3180 template<typename T1, typename op_type>
3181 inline
3182 const Mat<eT>&
3183 Mat<eT>::operator%=(const mtOp<eT, T1, op_type>& X)
3184 {
3185 arma_extra_debug_sigprint();
3186
3187 const Mat<eT> m(X);
3188
3189 return (*this).operator%=(m);
3190 }
3191
3192
3193
3194 //! EXPERIMENTAL
3195 template<typename eT>
3196 template<typename T1, typename op_type>
3197 inline
3198 const Mat<eT>&
3199 Mat<eT>::operator/=(const mtOp<eT, T1, op_type>& X)
3200 {
3201 arma_extra_debug_sigprint();
3202
3203 const Mat<eT> m(X);
3204
3205 return (*this).operator/=(m);
3206 }
3207
3208
3209
3210 //! create a matrix from Glue, i.e. run the previously delayed binary operations
3211 template<typename eT>
3212 template<typename T1, typename T2, typename glue_type>
3213 inline
3214 Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
3215 : n_rows(0)
3216 , n_cols(0)
3217 , n_elem(0)
3218 , vec_state(0)
3219 , mem_state(0)
3220 , mem()
3221 {
3222 arma_extra_debug_sigprint_this(this);
3223
3224 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3225 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3226
3227 glue_type::apply(*this, X);
3228 }
3229
3230
3231
3232 //! create a matrix from Glue, i.e. run the previously delayed binary operations
3233 template<typename eT>
3234 template<typename T1, typename T2, typename glue_type>
3235 inline
3236 const Mat<eT>&
3237 Mat<eT>::operator=(const Glue<T1, T2, glue_type>& X)
3238 {
3239 arma_extra_debug_sigprint();
3240
3241 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3242 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3243
3244 glue_type::apply(*this, X);
3245
3246 return *this;
3247 }
3248
3249
3250
3251 //! in-place matrix addition, with the right-hand-side operands having delayed operations
3252 template<typename eT>
3253 template<typename T1, typename T2, typename glue_type>
3254 inline
3255 const Mat<eT>&
3256 Mat<eT>::operator+=(const Glue<T1, T2, glue_type>& X)
3257 {
3258 arma_extra_debug_sigprint();
3259
3260 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3261 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3262
3263 const Mat<eT> m(X);
3264
3265 return (*this).operator+=(m);
3266 }
3267
3268
3269
3270 //! in-place matrix subtraction, with the right-hand-side operands having delayed operations
3271 template<typename eT>
3272 template<typename T1, typename T2, typename glue_type>
3273 inline
3274 const Mat<eT>&
3275 Mat<eT>::operator-=(const Glue<T1, T2, glue_type>& X)
3276 {
3277 arma_extra_debug_sigprint();
3278
3279 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3280 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3281
3282 const Mat<eT> m(X);
3283
3284 return (*this).operator-=(m);
3285 }
3286
3287
3288
3289 //! in-place matrix multiplications, with the right-hand-side operands having delayed operations
3290 template<typename eT>
3291 template<typename T1, typename T2, typename glue_type>
3292 inline
3293 const Mat<eT>&
3294 Mat<eT>::operator*=(const Glue<T1, T2, glue_type>& X)
3295 {
3296 arma_extra_debug_sigprint();
3297
3298 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3299 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3300
3301 glue_times::apply_inplace(*this, X);
3302
3303 return *this;
3304 }
3305
3306
3307
3308 //! in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
3309 template<typename eT>
3310 template<typename T1, typename T2, typename glue_type>
3311 inline
3312 const Mat<eT>&
3313 Mat<eT>::operator%=(const Glue<T1, T2, glue_type>& X)
3314 {
3315 arma_extra_debug_sigprint();
3316
3317 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3318 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3319
3320 const Mat<eT> m(X);
3321
3322 return (*this).operator%=(m);
3323 }
3324
3325
3326
3327 //! in-place matrix element-wise division, with the right-hand-side operands having delayed operations
3328 template<typename eT>
3329 template<typename T1, typename T2, typename glue_type>
3330 inline
3331 const Mat<eT>&
3332 Mat<eT>::operator/=(const Glue<T1, T2, glue_type>& X)
3333 {
3334 arma_extra_debug_sigprint();
3335
3336 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3337 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3338
3339 const Mat<eT> m(X);
3340
3341 return (*this).operator/=(m);
3342 }
3343
3344
3345
3346 template<typename eT>
3347 template<typename T1, typename T2>
3348 inline
3349 const Mat<eT>&
3350 Mat<eT>::operator+=(const Glue<T1, T2, glue_times>& X)
3351 {
3352 arma_extra_debug_sigprint();
3353
3354 glue_times::apply_inplace_plus(*this, X, sword(+1));
3355
3356 return *this;
3357 }
3358
3359
3360
3361 template<typename eT>
3362 template<typename T1, typename T2>
3363 inline
3364 const Mat<eT>&
3365 Mat<eT>::operator-=(const Glue<T1, T2, glue_times>& X)
3366 {
3367 arma_extra_debug_sigprint();
3368
3369 glue_times::apply_inplace_plus(*this, X, sword(-1));
3370
3371 return *this;
3372 }
3373
3374
3375
3376 //! create a matrix from eGlue, i.e. run the previously delayed binary operations
3377 template<typename eT>
3378 template<typename T1, typename T2, typename eglue_type>
3379 inline
3380 Mat<eT>::Mat(const eGlue<T1, T2, eglue_type>& X)
3381 : n_rows(X.get_n_rows())
3382 , n_cols(X.get_n_cols())
3383 , n_elem(X.get_n_elem())
3384 , vec_state(0)
3385 , mem_state(0)
3386 , mem()
3387 {
3388 arma_extra_debug_sigprint_this(this);
3389
3390 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3391 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3392
3393 init_cold();
3394
3395 eglue_type::apply(*this, X);
3396 }
3397
3398
3399
3400 //! create a matrix from eGlue, i.e. run the previously delayed binary operations
3401 template<typename eT>
3402 template<typename T1, typename T2, typename eglue_type>
3403 inline
3404 const Mat<eT>&
3405 Mat<eT>::operator=(const eGlue<T1, T2, eglue_type>& X)
3406 {
3407 arma_extra_debug_sigprint();
3408
3409 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3410 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3411
3412 const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || ( X.P2.has_subview && X.P2.is_alias(*this)) );
3413
3414 if(bad_alias == false)
3415 {
3416 init_warm(X.get_n_rows(), X.get_n_cols());
3417
3418 eglue_type::apply(*this, X);
3419 }
3420 else
3421 {
3422 Mat<eT> tmp(X);
3423
3424 steal_mem(tmp);
3425 }
3426
3427 return *this;
3428 }
3429
3430
3431
3432 //! in-place matrix addition, with the right-hand-side operands having delayed operations
3433 template<typename eT>
3434 template<typename T1, typename T2, typename eglue_type>
3435 inline
3436 const Mat<eT>&
3437 Mat<eT>::operator+=(const eGlue<T1, T2, eglue_type>& X)
3438 {
3439 arma_extra_debug_sigprint();
3440
3441 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3442 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3443
3444 eglue_type::apply_inplace_plus(*this, X);
3445
3446 return *this;
3447 }
3448
3449
3450
3451 //! in-place matrix subtraction, with the right-hand-side operands having delayed operations
3452 template<typename eT>
3453 template<typename T1, typename T2, typename eglue_type>
3454 inline
3455 const Mat<eT>&
3456 Mat<eT>::operator-=(const eGlue<T1, T2, eglue_type>& X)
3457 {
3458 arma_extra_debug_sigprint();
3459
3460 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3461 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3462
3463 eglue_type::apply_inplace_minus(*this, X);
3464
3465 return *this;
3466 }
3467
3468
3469
3470 template<typename eT>
3471 template<typename T1, typename T2, typename eglue_type>
3472 inline
3473 const Mat<eT>&
3474 Mat<eT>::operator*=(const eGlue<T1, T2, eglue_type>& X)
3475 {
3476 arma_extra_debug_sigprint();
3477
3478 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3479 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3480
3481 glue_times::apply_inplace(*this, X);
3482 return *this;
3483 }
3484
3485
3486
3487 template<typename eT>
3488 template<typename T1, typename T2, typename eglue_type>
3489 inline
3490 const Mat<eT>&
3491 Mat<eT>::operator%=(const eGlue<T1, T2, eglue_type>& X)
3492 {
3493 arma_extra_debug_sigprint();
3494
3495 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3496 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3497
3498 eglue_type::apply_inplace_schur(*this, X);
3499 return *this;
3500 }
3501
3502
3503
3504 template<typename eT>
3505 template<typename T1, typename T2, typename eglue_type>
3506 inline
3507 const Mat<eT>&
3508 Mat<eT>::operator/=(const eGlue<T1, T2, eglue_type>& X)
3509 {
3510 arma_extra_debug_sigprint();
3511
3512 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
3513 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
3514
3515 eglue_type::apply_inplace_div(*this, X);
3516 return *this;
3517 }
3518
3519
3520
3521 //! EXPERIMENTAL: create a matrix from mtGlue, i.e. run the previously delayed binary operations
3522 template<typename eT>
3523 template<typename T1, typename T2, typename glue_type>
3524 inline
3525 Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X)
3526 : n_rows(0)
3527 , n_cols(0)
3528 , n_elem(0)
3529 , vec_state(0)
3530 , mem_state(0)
3531 , mem()
3532 {
3533 arma_extra_debug_sigprint_this(this);
3534
3535 glue_type::apply(*this, X);
3536 }
3537
3538
3539
3540 //! EXPERIMENTAL: create a matrix from Glue, i.e. run the previously delayed binary operations
3541 template<typename eT>
3542 template<typename T1, typename T2, typename glue_type>
3543 inline
3544 const Mat<eT>&
3545 Mat<eT>::operator=(const mtGlue<eT, T1, T2, glue_type>& X)
3546 {
3547 arma_extra_debug_sigprint();
3548
3549 glue_type::apply(*this, X);
3550
3551 return *this;
3552 }
3553
3554
3555
3556 //! EXPERIMENTAL: in-place matrix addition, with the right-hand-side operands having delayed operations
3557 template<typename eT>
3558 template<typename T1, typename T2, typename glue_type>
3559 inline
3560 const Mat<eT>&
3561 Mat<eT>::operator+=(const mtGlue<eT, T1, T2, glue_type>& X)
3562 {
3563 arma_extra_debug_sigprint();
3564
3565 const Mat<eT> m(X);
3566
3567 return (*this).operator+=(m);
3568 }
3569
3570
3571
3572 //! EXPERIMENTAL: in-place matrix subtraction, with the right-hand-side operands having delayed operations
3573 template<typename eT>
3574 template<typename T1, typename T2, typename glue_type>
3575 inline
3576 const Mat<eT>&
3577 Mat<eT>::operator-=(const mtGlue<eT, T1, T2, glue_type>& X)
3578 {
3579 arma_extra_debug_sigprint();
3580
3581 const Mat<eT> m(X);
3582
3583 return (*this).operator-=(m);
3584 }
3585
3586
3587
3588 //! EXPERIMENTAL: in-place matrix multiplications, with the right-hand-side operands having delayed operations
3589 template<typename eT>
3590 template<typename T1, typename T2, typename glue_type>
3591 inline
3592 const Mat<eT>&
3593 Mat<eT>::operator*=(const mtGlue<eT, T1, T2, glue_type>& X)
3594 {
3595 arma_extra_debug_sigprint();
3596
3597 const Mat<eT> m(X);
3598
3599 glue_times::apply_inplace(*this, m);
3600
3601 return *this;
3602 }
3603
3604
3605
3606 //! EXPERIMENTAL: in-place matrix element-wise multiplication, with the right-hand-side operands having delayed operations
3607 template<typename eT>
3608 template<typename T1, typename T2, typename glue_type>
3609 inline
3610 const Mat<eT>&
3611 Mat<eT>::operator%=(const mtGlue<eT, T1, T2, glue_type>& X)
3612 {
3613 arma_extra_debug_sigprint();
3614
3615 const Mat<eT> m(X);
3616
3617 return (*this).operator%=(m);
3618 }
3619
3620
3621
3622 //! EXPERIMENTAL: in-place matrix element-wise division, with the right-hand-side operands having delayed operations
3623 template<typename eT>
3624 template<typename T1, typename T2, typename glue_type>
3625 inline
3626 const Mat<eT>&
3627 Mat<eT>::operator/=(const mtGlue<eT, T1, T2, glue_type>& X)
3628 {
3629 arma_extra_debug_sigprint();
3630
3631 const Mat<eT> m(X);
3632
3633 return (*this).operator/=(m);
3634 }
3635
3636
3637
3638 //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
3639 template<typename eT>
3640 arma_inline
3641 arma_warn_unused
3642 eT&
3643 Mat<eT>::operator() (const uword i)
3644 {
3645 arma_debug_check( (i >= n_elem), "Mat::operator(): out of bounds");
3646 return access::rw(mem[i]);
3647 }
3648
3649
3650
3651 //! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
3652 template<typename eT>
3653 arma_inline
3654 arma_warn_unused
3655 eT
3656 Mat<eT>::operator() (const uword i) const
3657 {
3658 arma_debug_check( (i >= n_elem), "Mat::operator(): out of bounds");
3659 return mem[i];
3660 }
3661
3662
3663 //! linear element accessor (treats the matrix as a vector); no bounds check.
3664 template<typename eT>
3665 arma_inline
3666 arma_warn_unused
3667 eT&
3668 Mat<eT>::operator[] (const uword i)
3669 {
3670 return access::rw(mem[i]);
3671 }
3672
3673
3674
3675 //! linear element accessor (treats the matrix as a vector); no bounds check
3676 template<typename eT>
3677 arma_inline
3678 arma_warn_unused
3679 eT
3680 Mat<eT>::operator[] (const uword i) const
3681 {
3682 return mem[i];
3683 }
3684
3685
3686
3687 //! linear element accessor (treats the matrix as a vector); no bounds check.
3688 template<typename eT>
3689 arma_inline
3690 arma_warn_unused
3691 eT&
3692 Mat<eT>::at(const uword i)
3693 {
3694 return access::rw(mem[i]);
3695 }
3696
3697
3698
3699 //! linear element accessor (treats the matrix as a vector); no bounds check
3700 template<typename eT>
3701 arma_inline
3702 arma_warn_unused
3703 eT
3704 Mat<eT>::at(const uword i) const
3705 {
3706 return mem[i];
3707 }
3708
3709
3710
3711 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
3712 template<typename eT>
3713 arma_inline
3714 arma_warn_unused
3715 eT&
3716 Mat<eT>::operator() (const uword in_row, const uword in_col)
3717 {
3718 arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): out of bounds");
3719 return access::rw(mem[in_row + in_col*n_rows]);
3720 }
3721
3722
3723
3724 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
3725 template<typename eT>
3726 arma_inline
3727 arma_warn_unused
3728 eT
3729 Mat<eT>::operator() (const uword in_row, const uword in_col) const
3730 {
3731 arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "Mat::operator(): out of bounds");
3732 return mem[in_row + in_col*n_rows];
3733 }
3734
3735
3736
3737 //! element accessor; no bounds check
3738 template<typename eT>
3739 arma_inline
3740 arma_warn_unused
3741 eT&
3742 Mat<eT>::at(const uword in_row, const uword in_col)
3743 {
3744 return access::rw( mem[in_row + in_col*n_rows] );
3745 }
3746
3747
3748
3749 //! element accessor; no bounds check
3750 template<typename eT>
3751 arma_inline
3752 arma_warn_unused
3753 eT
3754 Mat<eT>::at(const uword in_row, const uword in_col) const
3755 {
3756 return mem[in_row + in_col*n_rows];
3757 }
3758
3759
3760
3761 //! prefix ++
3762 template<typename eT>
3763 arma_inline
3764 const Mat<eT>&
3765 Mat<eT>::operator++()
3766 {
3767 Mat_aux::prefix_pp(*this);
3768 return *this;
3769 }
3770
3771
3772
3773 //! postfix ++ (must not return the object by reference)
3774 template<typename eT>
3775 arma_inline
3776 void
3777 Mat<eT>::operator++(int)
3778 {
3779 Mat_aux::postfix_pp(*this);
3780 }
3781
3782
3783
3784 //! prefix --
3785 template<typename eT>
3786 arma_inline
3787 const Mat<eT>&
3788 Mat<eT>::operator--()
3789 {
3790 Mat_aux::prefix_mm(*this);
3791 return *this;
3792 }
3793
3794
3795
3796 //! postfix -- (must not return the object by reference)
3797 template<typename eT>
3798 arma_inline
3799 void
3800 Mat<eT>::operator--(int)
3801 {
3802 Mat_aux::postfix_mm(*this);
3803 }
3804
3805
3806
3807 //! returns true if the matrix has no elements
3808 template<typename eT>
3809 arma_inline
3810 arma_warn_unused
3811 bool
3812 Mat<eT>::is_empty() const
3813 {
3814 return (n_elem == 0);
3815 }
3816
3817
3818
3819 //! returns true if the object can be interpreted as a column or row vector
3820 template<typename eT>
3821 arma_inline
3822 arma_warn_unused
3823 bool
3824 Mat<eT>::is_vec() const
3825 {
3826 return ( (n_rows == 1) || (n_cols == 1) );
3827 }
3828
3829
3830
3831 //! returns true if the object can be interpreted as a row vector
3832 template<typename eT>
3833 arma_inline
3834 arma_warn_unused
3835 bool
3836 Mat<eT>::is_rowvec() const
3837 {
3838 return (n_rows == 1);
3839 }
3840
3841
3842
3843 //! returns true if the object can be interpreted as a column vector
3844 template<typename eT>
3845 arma_inline
3846 arma_warn_unused
3847 bool
3848 Mat<eT>::is_colvec() const
3849 {
3850 return (n_cols == 1);
3851 }
3852
3853
3854
3855 //! returns true if the object has the same number of non-zero rows and columnns
3856 template<typename eT>
3857 arma_inline
3858 arma_warn_unused
3859 bool
3860 Mat<eT>::is_square() const
3861 {
3862 return (n_rows == n_cols);
3863 }
3864
3865
3866
3867 //! returns true if all of the elements are finite
3868 template<typename eT>
3869 inline
3870 arma_warn_unused
3871 bool
3872 Mat<eT>::is_finite() const
3873 {
3874 return arrayops::is_finite( memptr(), n_elem );
3875 }
3876
3877
3878
3879 //! returns true if the given index is currently in range
3880 template<typename eT>
3881 arma_inline
3882 arma_warn_unused
3883 bool
3884 Mat<eT>::in_range(const uword i) const
3885 {
3886 return (i < n_elem);
3887 }
3888
3889
3890
3891 //! returns true if the given start and end indices are currently in range
3892 template<typename eT>
3893 arma_inline
3894 arma_warn_unused
3895 bool
3896 Mat<eT>::in_range(const span& x) const
3897 {
3898 arma_extra_debug_sigprint();
3899
3900 if(x.whole == true)
3901 {
3902 return true;
3903 }
3904 else
3905 {
3906 const uword a = x.a;
3907 const uword b = x.b;
3908
3909 return ( (a <= b) && (b < n_elem) );
3910 }
3911 }
3912
3913
3914
3915 //! returns true if the given location is currently in range
3916 template<typename eT>
3917 arma_inline
3918 arma_warn_unused
3919 bool
3920 Mat<eT>::in_range(const uword in_row, const uword in_col) const
3921 {
3922 return ( (in_row < n_rows) && (in_col < n_cols) );
3923 }
3924
3925
3926
3927 template<typename eT>
3928 arma_inline
3929 arma_warn_unused
3930 bool
3931 Mat<eT>::in_range(const span& row_span, const uword in_col) const
3932 {
3933 arma_extra_debug_sigprint();
3934
3935 if(row_span.whole == true)
3936 {
3937 return (in_col < n_cols);
3938 }
3939 else
3940 {
3941 const uword in_row1 = row_span.a;
3942 const uword in_row2 = row_span.b;
3943
3944 return ( (in_row1 <= in_row2) && (in_row2 < n_rows) && (in_col < n_cols) );
3945 }
3946 }
3947
3948
3949
3950 template<typename eT>
3951 arma_inline
3952 arma_warn_unused
3953 bool
3954 Mat<eT>::in_range(const uword in_row, const span& col_span) const
3955 {
3956 arma_extra_debug_sigprint();
3957
3958 if(col_span.whole == true)
3959 {
3960 return (in_row < n_rows);
3961 }
3962 else
3963 {
3964 const uword in_col1 = col_span.a;
3965 const uword in_col2 = col_span.b;
3966
3967 return ( (in_row < n_rows) && (in_col1 <= in_col2) && (in_col2 < n_cols) );
3968 }
3969 }
3970
3971
3972
3973 template<typename eT>
3974 arma_inline
3975 arma_warn_unused
3976 bool
3977 Mat<eT>::in_range(const span& row_span, const span& col_span) const
3978 {
3979 arma_extra_debug_sigprint();
3980
3981 const uword in_row1 = row_span.a;
3982 const uword in_row2 = row_span.b;
3983
3984 const uword in_col1 = col_span.a;
3985 const uword in_col2 = col_span.b;
3986
3987 const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
3988 const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
3989
3990 return ( (rows_ok == true) && (cols_ok == true) );
3991 }
3992
3993
3994
3995 //! returns a pointer to array of eTs for a specified column; no bounds check
3996 template<typename eT>
3997 arma_inline
3998 arma_warn_unused
3999 eT*
4000 Mat<eT>::colptr(const uword in_col)
4001 {
4002 return & access::rw(mem[in_col*n_rows]);
4003 }
4004
4005
4006
4007 //! returns a pointer to array of eTs for a specified column; no bounds check
4008 template<typename eT>
4009 arma_inline
4010 arma_warn_unused
4011 const eT*
4012 Mat<eT>::colptr(const uword in_col) const
4013 {
4014 return & mem[in_col*n_rows];
4015 }
4016
4017
4018
4019 //! returns a pointer to array of eTs used by the matrix
4020 template<typename eT>
4021 arma_inline
4022 arma_warn_unused
4023 eT*
4024 Mat<eT>::memptr()
4025 {
4026 return const_cast<eT*>(mem);
4027 }
4028
4029
4030
4031 //! returns a pointer to array of eTs used by the matrix
4032 template<typename eT>
4033 arma_inline
4034 arma_warn_unused
4035 const eT*
4036 Mat<eT>::memptr() const
4037 {
4038 return mem;
4039 }
4040
4041
4042
4043 //! print contents of the matrix (to the cout stream),
4044 //! optionally preceding with a user specified line of text.
4045 //! the precision and cell width are modified.
4046 //! on return, the stream's state are restored to their original values.
4047 template<typename eT>
4048 inline
4049 void
4050 Mat<eT>::impl_print(const std::string& extra_text) const
4051 {
4052 arma_extra_debug_sigprint();
4053
4054 if(extra_text.length() != 0)
4055 {
4056 const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
4057
4058 ARMA_DEFAULT_OSTREAM << extra_text << '\n';
4059
4060 ARMA_DEFAULT_OSTREAM.width(orig_width);
4061 }
4062
4063 arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, true);
4064 }
4065
4066
4067
4068 //! print contents of the matrix to a user specified stream,
4069 //! optionally preceding with a user specified line of text.
4070 //! the precision and cell width are modified.
4071 //! on return, the stream's state are restored to their original values.
4072 template<typename eT>
4073 inline
4074 void
4075 Mat<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
4076 {
4077 arma_extra_debug_sigprint();
4078
4079 if(extra_text.length() != 0)
4080 {
4081 const std::streamsize orig_width = user_stream.width();
4082
4083 user_stream << extra_text << '\n';
4084
4085 user_stream.width(orig_width);
4086 }
4087
4088 arma_ostream::print(user_stream, *this, true);
4089 }
4090
4091
4092
4093 //! DEPRECATED FUNCTION
4094 template<typename eT>
4095 inline
4096 void
4097 Mat<eT>::impl_print_trans(const std::string& extra_text) const
4098 {
4099 arma_extra_debug_sigprint();
4100
4101 Mat<eT> tmp;
4102 op_strans::apply_noalias(tmp, *this);
4103
4104 tmp.impl_print(extra_text);
4105 }
4106
4107
4108
4109 //! DEPRECATED FUNCTION
4110 template<typename eT>
4111 inline
4112 void
4113 Mat<eT>::impl_print_trans(std::ostream& user_stream, const std::string& extra_text) const
4114 {
4115 arma_extra_debug_sigprint();
4116
4117 Mat<eT> tmp;
4118 op_strans::apply_noalias(tmp, *this);
4119
4120 tmp.impl_print(user_stream, extra_text);
4121 }
4122
4123
4124
4125 //! print contents of the matrix (to the cout stream),
4126 //! optionally preceding with a user specified line of text.
4127 //! the stream's state are used as is and are not modified
4128 //! (i.e. the precision and cell width are not modified).
4129 template<typename eT>
4130 inline
4131 void
4132 Mat<eT>::impl_raw_print(const std::string& extra_text) const
4133 {
4134 arma_extra_debug_sigprint();
4135
4136 if(extra_text.length() != 0)
4137 {
4138 const std::streamsize orig_width = ARMA_DEFAULT_OSTREAM.width();
4139
4140 ARMA_DEFAULT_OSTREAM << extra_text << '\n';
4141
4142 ARMA_DEFAULT_OSTREAM.width(orig_width);
4143 }
4144
4145 arma_ostream::print(ARMA_DEFAULT_OSTREAM, *this, false);
4146 }
4147
4148
4149
4150 //! print contents of the matrix to a user specified stream,
4151 //! optionally preceding with a user specified line of text.
4152 //! the stream's state are used as is and are not modified.
4153 //! (i.e. the precision and cell width are not modified).
4154 template<typename eT>
4155 inline
4156 void
4157 Mat<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
4158 {
4159 arma_extra_debug_sigprint();
4160
4161 if(extra_text.length() != 0)
4162 {
4163 const std::streamsize orig_width = user_stream.width();
4164
4165 user_stream << extra_text << '\n';
4166
4167 user_stream.width(orig_width);
4168 }
4169
4170 arma_ostream::print(user_stream, *this, false);
4171 }
4172
4173
4174
4175 //! DEPRECATED FUNCTION
4176 template<typename eT>
4177 inline
4178 void
4179 Mat<eT>::impl_raw_print_trans(const std::string& extra_text) const
4180 {
4181 arma_extra_debug_sigprint();
4182
4183 Mat<eT> tmp;
4184 op_strans::apply_noalias(tmp, *this);
4185
4186 tmp.impl_raw_print(extra_text);
4187 }
4188
4189
4190
4191 //! DEPRECATED FUNCTION
4192 template<typename eT>
4193 inline
4194 void
4195 Mat<eT>::impl_raw_print_trans(std::ostream& user_stream, const std::string& extra_text) const
4196 {
4197 arma_extra_debug_sigprint();
4198
4199 Mat<eT> tmp;
4200 op_strans::apply_noalias(tmp, *this);
4201
4202 tmp.impl_raw_print(user_stream, extra_text);
4203 }
4204
4205
4206
4207 //! change the matrix to have user specified dimensions (data is not preserved)
4208 template<typename eT>
4209 inline
4210 void
4211 Mat<eT>::set_size(const uword in_elem)
4212 {
4213 arma_extra_debug_sigprint();
4214
4215 switch(vec_state)
4216 {
4217 case 0:
4218 case 1:
4219 init_warm(in_elem, 1);
4220 break;
4221
4222 case 2:
4223 init_warm(1, in_elem);
4224 break;
4225
4226 default:
4227 ;
4228 }
4229 }
4230
4231
4232
4233 //! change the matrix to have user specified dimensions (data is not preserved)
4234 template<typename eT>
4235 inline
4236 void
4237 Mat<eT>::set_size(const uword in_rows, const uword in_cols)
4238 {
4239 arma_extra_debug_sigprint();
4240
4241 init_warm(in_rows, in_cols);
4242 }
4243
4244
4245
4246 //! change the matrix to have user specified dimensions (data is preserved)
4247 template<typename eT>
4248 inline
4249 void
4250 Mat<eT>::resize(const uword in_elem)
4251 {
4252 arma_extra_debug_sigprint();
4253
4254 switch(vec_state)
4255 {
4256 case 0:
4257 case 1:
4258 (*this).resize(in_elem, 1);
4259 break;
4260
4261 case 2:
4262 (*this).resize(1, in_elem);
4263 break;
4264
4265 default:
4266 ;
4267 }
4268 }
4269
4270
4271
4272 //! change the matrix to have user specified dimensions (data is preserved)
4273 template<typename eT>
4274 inline
4275 void
4276 Mat<eT>::resize(const uword in_rows, const uword in_cols)
4277 {
4278 arma_extra_debug_sigprint();
4279
4280 *this = arma::resize(*this, in_rows, in_cols);
4281 }
4282
4283
4284
4285 //! change the matrix to have user specified dimensions (data is preserved)
4286 template<typename eT>
4287 inline
4288 void
4289 Mat<eT>::reshape(const uword in_rows, const uword in_cols, const uword dim)
4290 {
4291 arma_extra_debug_sigprint();
4292
4293 *this = arma::reshape(*this, in_rows, in_cols, dim);
4294 }
4295
4296
4297
4298 //! change the matrix (without preserving data) to have the same dimensions as the given matrix
4299 template<typename eT>
4300 template<typename eT2>
4301 inline
4302 void
4303 Mat<eT>::copy_size(const Mat<eT2>& m)
4304 {
4305 arma_extra_debug_sigprint();
4306
4307 init_warm(m.n_rows, m.n_cols);
4308 }
4309
4310
4311
4312 //! fill the matrix with the specified value
4313 template<typename eT>
4314 arma_hot
4315 inline
4316 const Mat<eT>&
4317 Mat<eT>::fill(const eT val)
4318 {
4319 arma_extra_debug_sigprint();
4320
4321 arrayops::inplace_set( memptr(), val, n_elem );
4322
4323 return *this;
4324 }
4325
4326
4327
4328 template<typename eT>
4329 inline
4330 const Mat<eT>&
4331 Mat<eT>::zeros()
4332 {
4333 arma_extra_debug_sigprint();
4334
4335 return fill(eT(0));
4336 }
4337
4338
4339
4340 template<typename eT>
4341 inline
4342 const Mat<eT>&
4343 Mat<eT>::zeros(const uword in_elem)
4344 {
4345 arma_extra_debug_sigprint();
4346
4347 set_size(in_elem);
4348
4349 return fill(eT(0));
4350 }
4351
4352
4353
4354 template<typename eT>
4355 inline
4356 const Mat<eT>&
4357 Mat<eT>::zeros(const uword in_rows, const uword in_cols)
4358 {
4359 arma_extra_debug_sigprint();
4360
4361 set_size(in_rows, in_cols);
4362
4363 return fill(eT(0));
4364 }
4365
4366
4367
4368 template<typename eT>
4369 inline
4370 const Mat<eT>&
4371 Mat<eT>::ones()
4372 {
4373 arma_extra_debug_sigprint();
4374
4375 return fill(eT(1));
4376 }
4377
4378
4379
4380 template<typename eT>
4381 inline
4382 const Mat<eT>&
4383 Mat<eT>::ones(const uword in_elem)
4384 {
4385 arma_extra_debug_sigprint();
4386
4387 set_size(in_elem);
4388
4389 return fill(eT(1));
4390 }
4391
4392
4393
4394 template<typename eT>
4395 inline
4396 const Mat<eT>&
4397 Mat<eT>::ones(const uword in_rows, const uword in_cols)
4398 {
4399 arma_extra_debug_sigprint();
4400
4401 set_size(in_rows, in_cols);
4402
4403 return fill(eT(1));
4404 }
4405
4406
4407
4408 template<typename eT>
4409 inline
4410 const Mat<eT>&
4411 Mat<eT>::randu()
4412 {
4413 arma_extra_debug_sigprint();
4414
4415 const uword N = n_elem;
4416 eT* ptr = memptr();
4417
4418 uword i,j;
4419
4420 for(i=0, j=1; j<N; i+=2, j+=2)
4421 {
4422 const eT tmp_i = eT(eop_aux_randu<eT>());
4423 const eT tmp_j = eT(eop_aux_randu<eT>());
4424
4425 ptr[i] = tmp_i;
4426 ptr[j] = tmp_j;
4427 }
4428
4429 if(i < N)
4430 {
4431 ptr[i] = eT(eop_aux_randu<eT>());
4432 }
4433
4434 return *this;
4435 }
4436
4437
4438
4439 template<typename eT>
4440 inline
4441 const Mat<eT>&
4442 Mat<eT>::randu(const uword in_elem)
4443 {
4444 arma_extra_debug_sigprint();
4445
4446 set_size(in_elem);
4447
4448 return (*this).randu();
4449 }
4450
4451
4452
4453 template<typename eT>
4454 inline
4455 const Mat<eT>&
4456 Mat<eT>::randu(const uword in_rows, const uword in_cols)
4457 {
4458 arma_extra_debug_sigprint();
4459
4460 set_size(in_rows, in_cols);
4461
4462 return (*this).randu();
4463 }
4464
4465
4466
4467 template<typename eT>
4468 inline
4469 const Mat<eT>&
4470 Mat<eT>::randn()
4471 {
4472 arma_extra_debug_sigprint();
4473
4474 const uword N = n_elem;
4475 eT* ptr = memptr();
4476
4477 for(uword i=0; i<N; ++i)
4478 {
4479 ptr[i] = eT(eop_aux_randn<eT>());
4480 }
4481
4482 return *this;
4483 }
4484
4485
4486
4487 template<typename eT>
4488 inline
4489 const Mat<eT>&
4490 Mat<eT>::randn(const uword in_elem)
4491 {
4492 arma_extra_debug_sigprint();
4493
4494 set_size(in_elem);
4495
4496 return (*this).randn();
4497 }
4498
4499
4500
4501 template<typename eT>
4502 inline
4503 const Mat<eT>&
4504 Mat<eT>::randn(const uword in_rows, const uword in_cols)
4505 {
4506 arma_extra_debug_sigprint();
4507
4508 set_size(in_rows, in_cols);
4509
4510 return (*this).randn();
4511 }
4512
4513
4514
4515 template<typename eT>
4516 inline
4517 const Mat<eT>&
4518 Mat<eT>::eye()
4519 {
4520 arma_extra_debug_sigprint();
4521
4522 fill(eT(0));
4523
4524 const uword N = (std::min)(n_rows, n_cols);
4525
4526 for(uword i=0; i<N; ++i)
4527 {
4528 at(i,i) = eT(1);
4529 }
4530
4531 return *this;
4532 }
4533
4534
4535
4536 template<typename eT>
4537 inline
4538 const Mat<eT>&
4539 Mat<eT>::eye(const uword in_rows, const uword in_cols)
4540 {
4541 arma_extra_debug_sigprint();
4542
4543 set_size(in_rows, in_cols);
4544
4545 return (*this).eye();
4546 }
4547
4548
4549
4550 template<typename eT>
4551 inline
4552 void
4553 Mat<eT>::reset()
4554 {
4555 arma_extra_debug_sigprint();
4556
4557 switch(vec_state)
4558 {
4559 default:
4560 init_warm(0, 0);
4561 break;
4562
4563 case 1:
4564 init_warm(0, 1);
4565 break;
4566
4567 case 2:
4568 init_warm(1, 0);
4569 break;
4570 }
4571 }
4572
4573
4574
4575 template<typename eT>
4576 template<typename T1>
4577 inline
4578 void
4579 Mat<eT>::set_real(const Base<typename Mat<eT>::pod_type,T1>& X)
4580 {
4581 arma_extra_debug_sigprint();
4582
4583 Mat_aux::set_real(*this, X);
4584 }
4585
4586
4587
4588 template<typename eT>
4589 template<typename T1>
4590 inline
4591 void
4592 Mat<eT>::set_imag(const Base<typename Mat<eT>::pod_type,T1>& X)
4593 {
4594 arma_extra_debug_sigprint();
4595
4596 Mat_aux::set_imag(*this, X);
4597 }
4598
4599
4600
4601 template<typename eT>
4602 inline
4603 arma_warn_unused
4604 eT
4605 Mat<eT>::min() const
4606 {
4607 arma_extra_debug_sigprint();
4608
4609 arma_debug_check( (n_elem == 0), "min(): object has no elements" );
4610
4611 return op_min::direct_min(memptr(), n_elem);
4612 }
4613
4614
4615
4616 template<typename eT>
4617 inline
4618 arma_warn_unused
4619 eT
4620 Mat<eT>::max() const
4621 {
4622 arma_extra_debug_sigprint();
4623
4624 arma_debug_check( (n_elem == 0), "max(): object has no elements" );
4625
4626 return op_max::direct_max(memptr(), n_elem);
4627 }
4628
4629
4630
4631 template<typename eT>
4632 inline
4633 eT
4634 Mat<eT>::min(uword& index_of_min_val) const
4635 {
4636 arma_extra_debug_sigprint();
4637
4638 arma_debug_check( (n_elem == 0), "min(): object has no elements" );
4639
4640 return op_min::direct_min(memptr(), n_elem, index_of_min_val);
4641 }
4642
4643
4644
4645 template<typename eT>
4646 inline
4647 eT
4648 Mat<eT>::max(uword& index_of_max_val) const
4649 {
4650 arma_extra_debug_sigprint();
4651
4652 arma_debug_check( (n_elem == 0), "max(): object has no elements" );
4653
4654 return op_max::direct_max(memptr(), n_elem, index_of_max_val);
4655 }
4656
4657
4658
4659 template<typename eT>
4660 inline
4661 eT
4662 Mat<eT>::min(uword& row_of_min_val, uword& col_of_min_val) const
4663 {
4664 arma_extra_debug_sigprint();
4665
4666 arma_debug_check( (n_elem == 0), "min(): object has no elements" );
4667
4668 uword i;
4669
4670 eT val = op_min::direct_min(memptr(), n_elem, i);
4671
4672 row_of_min_val = i % n_rows;
4673 col_of_min_val = i / n_rows;
4674
4675 return val;
4676 }
4677
4678
4679
4680 template<typename eT>
4681 inline
4682 eT
4683 Mat<eT>::max(uword& row_of_max_val, uword& col_of_max_val) const
4684 {
4685 arma_extra_debug_sigprint();
4686
4687 arma_debug_check( (n_elem == 0), "max(): object has no elements" );
4688
4689 uword i;
4690
4691 eT val = op_max::direct_max(memptr(), n_elem, i);
4692
4693 row_of_max_val = i % n_rows;
4694 col_of_max_val = i / n_rows;
4695
4696 return val;
4697 }
4698
4699
4700
4701 //! save the matrix to a file
4702 template<typename eT>
4703 inline
4704 bool
4705 Mat<eT>::save(const std::string name, const file_type type, const bool print_status) const
4706 {
4707 arma_extra_debug_sigprint();
4708
4709 bool save_okay;
4710
4711 switch(type)
4712 {
4713 case raw_ascii:
4714 save_okay = diskio::save_raw_ascii(*this, name);
4715 break;
4716
4717 case arma_ascii:
4718 save_okay = diskio::save_arma_ascii(*this, name);
4719 break;
4720
4721 case csv_ascii:
4722 save_okay = diskio::save_csv_ascii(*this, name);
4723 break;
4724
4725 case raw_binary:
4726 save_okay = diskio::save_raw_binary(*this, name);
4727 break;
4728
4729 case arma_binary:
4730 save_okay = diskio::save_arma_binary(*this, name);
4731 break;
4732
4733 case pgm_binary:
4734 save_okay = diskio::save_pgm_binary(*this, name);
4735 break;
4736
4737 default:
4738 arma_warn(print_status, "Mat::save(): unsupported file type");
4739 save_okay = false;
4740 }
4741
4742 arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to ", name);
4743
4744 return save_okay;
4745 }
4746
4747
4748
4749 //! save the matrix to a stream
4750 template<typename eT>
4751 inline
4752 bool
4753 Mat<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
4754 {
4755 arma_extra_debug_sigprint();
4756
4757 bool save_okay;
4758
4759 switch(type)
4760 {
4761 case raw_ascii:
4762 save_okay = diskio::save_raw_ascii(*this, os);
4763 break;
4764
4765 case arma_ascii:
4766 save_okay = diskio::save_arma_ascii(*this, os);
4767 break;
4768
4769 case csv_ascii:
4770 save_okay = diskio::save_csv_ascii(*this, os);
4771 break;
4772
4773 case raw_binary:
4774 save_okay = diskio::save_raw_binary(*this, os);
4775 break;
4776
4777 case arma_binary:
4778 save_okay = diskio::save_arma_binary(*this, os);
4779 break;
4780
4781 case pgm_binary:
4782 save_okay = diskio::save_pgm_binary(*this, os);
4783 break;
4784
4785 default:
4786 arma_warn(print_status, "Mat::save(): unsupported file type");
4787 save_okay = false;
4788 }
4789
4790 arma_warn( (print_status && (save_okay == false)), "Mat::save(): couldn't write to the given stream");
4791
4792 return save_okay;
4793 }
4794
4795
4796
4797 //! load a matrix from a file
4798 template<typename eT>
4799 inline
4800 bool
4801 Mat<eT>::load(const std::string name, const file_type type, const bool print_status)
4802 {
4803 arma_extra_debug_sigprint();
4804
4805 bool load_okay;
4806 std::string err_msg;
4807
4808 switch(type)
4809 {
4810 case auto_detect:
4811 load_okay = diskio::load_auto_detect(*this, name, err_msg);
4812 break;
4813
4814 case raw_ascii:
4815 load_okay = diskio::load_raw_ascii(*this, name, err_msg);
4816 break;
4817
4818 case arma_ascii:
4819 load_okay = diskio::load_arma_ascii(*this, name, err_msg);
4820 break;
4821
4822 case csv_ascii:
4823 load_okay = diskio::load_csv_ascii(*this, name, err_msg);
4824 break;
4825
4826 case raw_binary:
4827 load_okay = diskio::load_raw_binary(*this, name, err_msg);
4828 break;
4829
4830 case arma_binary:
4831 load_okay = diskio::load_arma_binary(*this, name, err_msg);
4832 break;
4833
4834 case pgm_binary:
4835 load_okay = diskio::load_pgm_binary(*this, name, err_msg);
4836 break;
4837
4838 default:
4839 arma_warn(print_status, "Mat::load(): unsupported file type");
4840 load_okay = false;
4841 }
4842
4843 if( (print_status == true) && (load_okay == false) )
4844 {
4845 if(err_msg.length() > 0)
4846 {
4847 arma_warn(true, "Mat::load(): ", err_msg, name);
4848 }
4849 else
4850 {
4851 arma_warn(true, "Mat::load(): couldn't read ", name);
4852 }
4853 }
4854
4855 if(load_okay == false)
4856 {
4857 (*this).reset();
4858 }
4859
4860 return load_okay;
4861 }
4862
4863
4864
4865 //! load a matrix from a stream
4866 template<typename eT>
4867 inline
4868 bool
4869 Mat<eT>::load(std::istream& is, const file_type type, const bool print_status)
4870 {
4871 arma_extra_debug_sigprint();
4872
4873 bool load_okay;
4874 std::string err_msg;
4875
4876 switch(type)
4877 {
4878 case auto_detect:
4879 load_okay = diskio::load_auto_detect(*this, is, err_msg);
4880 break;
4881
4882 case raw_ascii:
4883 load_okay = diskio::load_raw_ascii(*this, is, err_msg);
4884 break;
4885
4886 case arma_ascii:
4887 load_okay = diskio::load_arma_ascii(*this, is, err_msg);
4888 break;
4889
4890 case csv_ascii:
4891 load_okay = diskio::load_csv_ascii(*this, is, err_msg);
4892 break;
4893
4894 case raw_binary:
4895 load_okay = diskio::load_raw_binary(*this, is, err_msg);
4896 break;
4897
4898 case arma_binary:
4899 load_okay = diskio::load_arma_binary(*this, is, err_msg);
4900 break;
4901
4902 case pgm_binary:
4903 load_okay = diskio::load_pgm_binary(*this, is, err_msg);
4904 break;
4905
4906 default:
4907 arma_warn(print_status, "Mat::load(): unsupported file type");
4908 load_okay = false;
4909 }
4910
4911
4912 if( (print_status == true) && (load_okay == false) )
4913 {
4914 if(err_msg.length() > 0)
4915 {
4916 arma_warn(true, "Mat::load(): ", err_msg, "the given stream");
4917 }
4918 else
4919 {
4920 arma_warn(true, "Mat::load(): couldn't load from the given stream");
4921 }
4922 }
4923
4924 if(load_okay == false)
4925 {
4926 (*this).reset();
4927 }
4928
4929 return load_okay;
4930 }
4931
4932
4933
4934 //! save the matrix to a file, without printing any error messages
4935 template<typename eT>
4936 inline
4937 bool
4938 Mat<eT>::quiet_save(const std::string name, const file_type type) const
4939 {
4940 arma_extra_debug_sigprint();
4941
4942 return (*this).save(name, type, false);
4943 }
4944
4945
4946
4947 //! save the matrix to a stream, without printing any error messages
4948 template<typename eT>
4949 inline
4950 bool
4951 Mat<eT>::quiet_save(std::ostream& os, const file_type type) const
4952 {
4953 arma_extra_debug_sigprint();
4954
4955 return (*this).save(os, type, false);
4956 }
4957
4958
4959
4960 //! load a matrix from a file, without printing any error messages
4961 template<typename eT>
4962 inline
4963 bool
4964 Mat<eT>::quiet_load(const std::string name, const file_type type)
4965 {
4966 arma_extra_debug_sigprint();
4967
4968 return (*this).load(name, type, false);
4969 }
4970
4971
4972
4973 //! load a matrix from a stream, without printing any error messages
4974 template<typename eT>
4975 inline
4976 bool
4977 Mat<eT>::quiet_load(std::istream& is, const file_type type)
4978 {
4979 arma_extra_debug_sigprint();
4980
4981 return (*this).load(is, type, false);
4982 }
4983
4984
4985
4986 template<typename eT>
4987 inline
4988 Mat<eT>::row_iterator::row_iterator(Mat<eT>& in_M, const uword in_row)
4989 : M (in_M )
4990 , row(in_row)
4991 , col(0 )
4992 {
4993 arma_extra_debug_sigprint();
4994 }
4995
4996
4997
4998 template<typename eT>
4999 inline
5000 eT&
5001 Mat<eT>::row_iterator::operator*()
5002 {
5003 return M.at(row,col);
5004 }
5005
5006
5007
5008 template<typename eT>
5009 inline
5010 typename Mat<eT>::row_iterator&
5011 Mat<eT>::row_iterator::operator++()
5012 {
5013 ++col;
5014
5015 if(col >= M.n_cols)
5016 {
5017 col = 0;
5018 ++row;
5019 }
5020
5021 return *this;
5022 }
5023
5024
5025
5026 template<typename eT>
5027 inline
5028 void
5029 Mat<eT>::row_iterator::operator++(int)
5030 {
5031 operator++();
5032 }
5033
5034
5035
5036 template<typename eT>
5037 inline
5038 typename Mat<eT>::row_iterator&
5039 Mat<eT>::row_iterator::operator--()
5040 {
5041 if(col > 0)
5042 {
5043 --col;
5044 }
5045 else
5046 {
5047 if(row > 0)
5048 {
5049 col = M.n_cols - 1;
5050 --row;
5051 }
5052 }
5053
5054 return *this;
5055 }
5056
5057
5058
5059 template<typename eT>
5060 inline
5061 void
5062 Mat<eT>::row_iterator::operator--(int)
5063 {
5064 operator--();
5065 }
5066
5067
5068
5069 template<typename eT>
5070 inline
5071 bool
5072 Mat<eT>::row_iterator::operator!=(const typename Mat<eT>::row_iterator& X) const
5073 {
5074 return ( (row != X.row) || (col != X.col) ) ? true : false;
5075 }
5076
5077
5078
5079 template<typename eT>
5080 inline
5081 bool
5082 Mat<eT>::row_iterator::operator==(const typename Mat<eT>::row_iterator& X) const
5083 {
5084 return ( (row == X.row) && (col == X.col) ) ? true : false;
5085 }
5086
5087
5088
5089 template<typename eT>
5090 inline
5091 Mat<eT>::const_row_iterator::const_row_iterator(const Mat<eT>& in_M, const uword in_row)
5092 : M (in_M )
5093 , row(in_row)
5094 , col(0 )
5095 {
5096 arma_extra_debug_sigprint();
5097 }
5098
5099
5100
5101 template<typename eT>
5102 inline
5103 Mat<eT>::const_row_iterator::const_row_iterator(const typename Mat<eT>::row_iterator& X)
5104 : M (X.M)
5105 , row(X.row)
5106 , col(X.col)
5107 {
5108 arma_extra_debug_sigprint();
5109 }
5110
5111
5112
5113 template<typename eT>
5114 inline
5115 eT
5116 Mat<eT>::const_row_iterator::operator*() const
5117 {
5118 return M.at(row,col);
5119 }
5120
5121
5122
5123 template<typename eT>
5124 inline
5125 typename Mat<eT>::const_row_iterator&
5126 Mat<eT>::const_row_iterator::operator++()
5127 {
5128 ++col;
5129
5130 if(col >= M.n_cols)
5131 {
5132 col = 0;
5133 ++row;
5134 }
5135
5136 return *this;
5137 }
5138
5139
5140
5141 template<typename eT>
5142 inline
5143 void
5144 Mat<eT>::const_row_iterator::operator++(int)
5145 {
5146 operator++();
5147 }
5148
5149
5150
5151 template<typename eT>
5152 inline
5153 typename Mat<eT>::const_row_iterator&
5154 Mat<eT>::const_row_iterator::operator--()
5155 {
5156 if(col > 0)
5157 {
5158 --col;
5159 }
5160 else
5161 {
5162 if(row > 0)
5163 {
5164 col = M.n_cols - 1;
5165 --row;
5166 }
5167 }
5168
5169 return *this;
5170 }
5171
5172
5173
5174 template<typename eT>
5175 inline
5176 void
5177 Mat<eT>::const_row_iterator::operator--(int)
5178 {
5179 operator--();
5180 }
5181
5182
5183
5184 template<typename eT>
5185 inline
5186 bool
5187 Mat<eT>::const_row_iterator::operator!=(const typename Mat<eT>::const_row_iterator& X) const
5188 {
5189 return ( (row != X.row) || (col != X.col) ) ? true : false;
5190 }
5191
5192
5193
5194 template<typename eT>
5195 inline
5196 bool
5197 Mat<eT>::const_row_iterator::operator==(const typename Mat<eT>::const_row_iterator& X) const
5198 {
5199 return ( (row == X.row) && (col == X.col) ) ? true : false;
5200 }
5201
5202
5203
5204 template<typename eT>
5205 inline
5206 typename Mat<eT>::iterator
5207 Mat<eT>::begin()
5208 {
5209 arma_extra_debug_sigprint();
5210
5211 return memptr();
5212 }
5213
5214
5215
5216 template<typename eT>
5217 inline
5218 typename Mat<eT>::const_iterator
5219 Mat<eT>::begin() const
5220 {
5221 arma_extra_debug_sigprint();
5222
5223 return memptr();
5224 }
5225
5226
5227
5228 template<typename eT>
5229 inline
5230 typename Mat<eT>::iterator
5231 Mat<eT>::end()
5232 {
5233 arma_extra_debug_sigprint();
5234
5235 return memptr() + n_elem;
5236 }
5237
5238
5239
5240 template<typename eT>
5241 inline
5242 typename Mat<eT>::const_iterator
5243 Mat<eT>::end() const
5244 {
5245 arma_extra_debug_sigprint();
5246
5247 return memptr() + n_elem;
5248 }
5249
5250
5251
5252 template<typename eT>
5253 inline
5254 typename Mat<eT>::col_iterator
5255 Mat<eT>::begin_col(const uword col_num)
5256 {
5257 arma_extra_debug_sigprint();
5258
5259 arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds");
5260
5261 return colptr(col_num);
5262 }
5263
5264
5265
5266 template<typename eT>
5267 inline
5268 typename Mat<eT>::const_col_iterator
5269 Mat<eT>::begin_col(const uword col_num) const
5270 {
5271 arma_extra_debug_sigprint();
5272
5273 arma_debug_check( (col_num >= n_cols), "begin_col(): index out of bounds");
5274
5275 return colptr(col_num);
5276 }
5277
5278
5279
5280 template<typename eT>
5281 inline
5282 typename Mat<eT>::col_iterator
5283 Mat<eT>::end_col(const uword col_num)
5284 {
5285 arma_extra_debug_sigprint();
5286
5287 arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds");
5288
5289 return colptr(col_num) + n_rows;
5290 }
5291
5292
5293
5294 template<typename eT>
5295 inline
5296 typename Mat<eT>::const_col_iterator
5297 Mat<eT>::end_col(const uword col_num) const
5298 {
5299 arma_extra_debug_sigprint();
5300
5301 arma_debug_check( (col_num >= n_cols), "end_col(): index out of bounds");
5302
5303 return colptr(col_num) + n_rows;
5304 }
5305
5306
5307
5308 template<typename eT>
5309 inline
5310 typename Mat<eT>::row_iterator
5311 Mat<eT>::begin_row(const uword row_num)
5312 {
5313 arma_extra_debug_sigprint();
5314
5315 arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
5316
5317 return typename Mat<eT>::row_iterator(*this, row_num);
5318 }
5319
5320
5321
5322 template<typename eT>
5323 inline
5324 typename Mat<eT>::const_row_iterator
5325 Mat<eT>::begin_row(const uword row_num) const
5326 {
5327 arma_extra_debug_sigprint();
5328
5329 arma_debug_check( (row_num >= n_rows), "Mat::begin_row(): index out of bounds" );
5330
5331 return typename Mat<eT>::const_row_iterator(*this, row_num);
5332 }
5333
5334
5335
5336 template<typename eT>
5337 inline
5338 typename Mat<eT>::row_iterator
5339 Mat<eT>::end_row(const uword row_num)
5340 {
5341 arma_extra_debug_sigprint();
5342
5343 arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
5344
5345 return typename Mat<eT>::row_iterator(*this, row_num + 1);
5346 }
5347
5348
5349
5350 template<typename eT>
5351 inline
5352 typename Mat<eT>::const_row_iterator
5353 Mat<eT>::end_row(const uword row_num) const
5354 {
5355 arma_extra_debug_sigprint();
5356
5357 arma_debug_check( (row_num >= n_rows), "Mat::end_row(): index out of bounds" );
5358
5359 return typename Mat<eT>::const_row_iterator(*this, row_num + 1);
5360 }
5361
5362
5363
5364 //! resets this matrix to an empty matrix
5365 template<typename eT>
5366 inline
5367 void
5368 Mat<eT>::clear()
5369 {
5370 reset();
5371 }
5372
5373
5374
5375 //! returns true if the matrix has no elements
5376 template<typename eT>
5377 inline
5378 bool
5379 Mat<eT>::empty() const
5380 {
5381 return (n_elem == 0);
5382 }
5383
5384
5385
5386 //! returns the number of elements in this matrix
5387 template<typename eT>
5388 inline
5389 uword
5390 Mat<eT>::size() const
5391 {
5392 return n_elem;
5393 }
5394
5395
5396
5397 template<typename eT>
5398 template<uword fixed_n_rows, uword fixed_n_cols>
5399 arma_inline
5400 void
5401 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::mem_setup()
5402 {
5403 arma_extra_debug_sigprint();
5404
5405 access::rw(Mat<eT>::n_rows) = fixed_n_rows;
5406 access::rw(Mat<eT>::n_cols) = fixed_n_cols;
5407 access::rw(Mat<eT>::n_elem) = fixed_n_elem;
5408 access::rw(Mat<eT>::vec_state) = 0;
5409 access::rw(Mat<eT>::mem_state) = 3;
5410 access::rw(Mat<eT>::mem) = (use_extra) ? mem_local_extra : mem_local;
5411 }
5412
5413
5414
5415 template<typename eT>
5416 template<uword fixed_n_rows, uword fixed_n_cols>
5417 arma_inline
5418 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed()
5419 {
5420 arma_extra_debug_sigprint_this(this);
5421
5422 mem_setup();
5423 }
5424
5425
5426
5427 template<typename eT>
5428 template<uword fixed_n_rows, uword fixed_n_cols>
5429 arma_inline
5430 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fixed<fixed_n_rows, fixed_n_cols>& X)
5431 {
5432 arma_extra_debug_sigprint_this(this);
5433
5434 mem_setup();
5435
5436 eT* dest = (use_extra) ? mem_local_extra : mem_local;
5437
5438 arrayops::copy( dest, X.mem, fixed_n_elem );
5439 }
5440
5441
5442
5443 template<typename eT>
5444 template<uword fixed_n_rows, uword fixed_n_cols>
5445 template<typename T1>
5446 inline
5447 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<eT,T1>& A)
5448 {
5449 arma_extra_debug_sigprint_this(this);
5450
5451 mem_setup();
5452
5453 Mat<eT>::operator=(A.get_ref());
5454 }
5455
5456
5457
5458 template<typename eT>
5459 template<uword fixed_n_rows, uword fixed_n_cols>
5460 template<typename T1, typename T2>
5461 inline
5462 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const Base<pod_type,T1>& A, const Base<pod_type,T2>& B)
5463 {
5464 arma_extra_debug_sigprint_this(this);
5465
5466 mem_setup();
5467
5468 Mat<eT>::init(A,B);
5469 }
5470
5471
5472
5473 template<typename eT>
5474 template<uword fixed_n_rows, uword fixed_n_cols>
5475 inline
5476 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(eT* aux_mem, const bool copy_aux_mem)
5477 {
5478 arma_extra_debug_sigprint_this(this);
5479
5480 access::rw(Mat<eT>::n_rows) = fixed_n_rows;
5481 access::rw(Mat<eT>::n_cols) = fixed_n_cols;
5482 access::rw(Mat<eT>::n_elem) = fixed_n_elem;
5483 access::rw(Mat<eT>::vec_state) = 0;
5484 access::rw(Mat<eT>::mem_state) = 3;
5485
5486 if(copy_aux_mem == true)
5487 {
5488 eT* dest = (use_extra) ? mem_local_extra : mem_local;
5489
5490 access::rw(Mat<eT>::mem) = dest;
5491
5492 arrayops::copy( dest, aux_mem, fixed_n_elem );
5493 }
5494 else
5495 {
5496 access::rw(Mat<eT>::mem) = aux_mem;
5497 }
5498 }
5499
5500
5501
5502 template<typename eT>
5503 template<uword fixed_n_rows, uword fixed_n_cols>
5504 inline
5505 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const eT* aux_mem)
5506 {
5507 arma_extra_debug_sigprint_this(this);
5508
5509 mem_setup();
5510
5511 arrayops::copy( const_cast<eT*>(Mat<eT>::mem), aux_mem, fixed_n_elem );
5512 }
5513
5514
5515
5516 template<typename eT>
5517 template<uword fixed_n_rows, uword fixed_n_cols>
5518 inline
5519 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const char* text)
5520 {
5521 arma_extra_debug_sigprint_this(this);
5522
5523 mem_setup();
5524
5525 Mat<eT>::operator=(text);
5526 }
5527
5528
5529
5530 template<typename eT>
5531 template<uword fixed_n_rows, uword fixed_n_cols>
5532 inline
5533 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const std::string& text)
5534 {
5535 arma_extra_debug_sigprint_this(this);
5536
5537 mem_setup();
5538
5539 Mat<eT>::operator=(text);
5540 }
5541
5542
5543
5544 template<typename eT>
5545 template<uword fixed_n_rows, uword fixed_n_cols>
5546 template<typename T1>
5547 inline
5548 const Mat<eT>&
5549 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const Base<eT,T1>& A)
5550 {
5551 Mat<eT>::operator=(A.get_ref());
5552
5553 return *this;
5554 }
5555
5556
5557
5558 template<typename eT>
5559 template<uword fixed_n_rows, uword fixed_n_cols>
5560 inline
5561 const Mat<eT>&
5562 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const eT val)
5563 {
5564 arma_extra_debug_sigprint();
5565
5566 Mat<eT>::operator=(val);
5567
5568 return *this;
5569 }
5570
5571
5572
5573 template<typename eT>
5574 template<uword fixed_n_rows, uword fixed_n_cols>
5575 inline
5576 const Mat<eT>&
5577 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const char* text)
5578 {
5579 arma_extra_debug_sigprint();
5580
5581 Mat<eT>::operator=(text);
5582
5583 return *this;
5584 }
5585
5586
5587
5588 template<typename eT>
5589 template<uword fixed_n_rows, uword fixed_n_cols>
5590 inline
5591 const Mat<eT>&
5592 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator=(const std::string& text)
5593 {
5594 arma_extra_debug_sigprint();
5595
5596 Mat<eT>::operator=(text);
5597
5598 return *this;
5599 }
5600
5601
5602
5603 template<typename eT>
5604 template<uword fixed_n_rows, uword fixed_n_cols>
5605 inline
5606 subview_row<eT>
5607 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const uword row_num, const span& col_span)
5608 {
5609 arma_extra_debug_sigprint();
5610
5611 return Mat<eT>::operator()(row_num, col_span);
5612 }
5613
5614
5615
5616 template<typename eT>
5617 template<uword fixed_n_rows, uword fixed_n_cols>
5618 inline
5619 const subview_row<eT>
5620 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const uword row_num, const span& col_span) const
5621 {
5622 arma_extra_debug_sigprint();
5623
5624 return Mat<eT>::operator()(row_num, col_span);
5625 }
5626
5627
5628
5629 template<typename eT>
5630 template<uword fixed_n_rows, uword fixed_n_cols>
5631 inline
5632 subview_col<eT>
5633 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const uword col_num)
5634 {
5635 arma_extra_debug_sigprint();
5636
5637 return Mat<eT>::operator()(row_span, col_num);
5638 }
5639
5640
5641
5642 template<typename eT>
5643 template<uword fixed_n_rows, uword fixed_n_cols>
5644 inline
5645 const subview_col<eT>
5646 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const uword col_num) const
5647 {
5648 arma_extra_debug_sigprint();
5649
5650 return Mat<eT>::operator()(row_span, col_num);
5651 }
5652
5653
5654
5655 template<typename eT>
5656 template<uword fixed_n_rows, uword fixed_n_cols>
5657 inline
5658 subview<eT>
5659 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const span& col_span)
5660 {
5661 arma_extra_debug_sigprint();
5662
5663 return Mat<eT>::operator()(row_span, col_span);
5664 }
5665
5666
5667
5668 template<typename eT>
5669 template<uword fixed_n_rows, uword fixed_n_cols>
5670 inline
5671 const subview<eT>
5672 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator()(const span& row_span, const span& col_span) const
5673 {
5674 arma_extra_debug_sigprint();
5675
5676 return Mat<eT>::operator()(row_span, col_span);
5677 }
5678
5679
5680
5681 template<typename eT>
5682 template<uword fixed_n_rows, uword fixed_n_cols>
5683 arma_inline
5684 arma_warn_unused
5685 eT&
5686 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword i)
5687 {
5688 return access::rw( Mat<eT>::mem[i] );
5689 }
5690
5691
5692
5693 template<typename eT>
5694 template<uword fixed_n_rows, uword fixed_n_cols>
5695 arma_inline
5696 arma_warn_unused
5697 eT
5698 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator[] (const uword i) const
5699 {
5700 return ( Mat<eT>::mem[i] );
5701 }
5702
5703
5704
5705 template<typename eT>
5706 template<uword fixed_n_rows, uword fixed_n_cols>
5707 arma_inline
5708 arma_warn_unused
5709 eT&
5710 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword i)
5711 {
5712 return access::rw( Mat<eT>::mem[i] );
5713 }
5714
5715
5716
5717 template<typename eT>
5718 template<uword fixed_n_rows, uword fixed_n_cols>
5719 arma_inline
5720 arma_warn_unused
5721 eT
5722 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword i) const
5723 {
5724 return ( Mat<eT>::mem[i] );
5725 }
5726
5727
5728
5729 template<typename eT>
5730 template<uword fixed_n_rows, uword fixed_n_cols>
5731 arma_inline
5732 arma_warn_unused
5733 eT&
5734 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword i)
5735 {
5736 arma_debug_check( (i >= fixed_n_elem), "Mat::fixed::operator(): out of bounds");
5737
5738 return access::rw( Mat<eT>::mem[i] );
5739 }
5740
5741
5742
5743 template<typename eT>
5744 template<uword fixed_n_rows, uword fixed_n_cols>
5745 arma_inline
5746 arma_warn_unused
5747 eT
5748 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword i) const
5749 {
5750 arma_debug_check( (i >= fixed_n_elem), "Mat::fixed::operator(): out of bounds");
5751
5752 return ( Mat<eT>::mem[i] );
5753 }
5754
5755
5756
5757 template<typename eT>
5758 template<uword fixed_n_rows, uword fixed_n_cols>
5759 arma_inline
5760 arma_warn_unused
5761 eT&
5762 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col)
5763 {
5764 const uword i = in_row + in_col*fixed_n_rows;
5765
5766 return access::rw( Mat<eT>::mem[i] );
5767 }
5768
5769
5770
5771 template<typename eT>
5772 template<uword fixed_n_rows, uword fixed_n_cols>
5773 arma_inline
5774 arma_warn_unused
5775 eT
5776 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::at(const uword in_row, const uword in_col) const
5777 {
5778 const uword i = in_row + in_col*fixed_n_rows;
5779
5780 return ( Mat<eT>::mem[i] );
5781 }
5782
5783
5784
5785 template<typename eT>
5786 template<uword fixed_n_rows, uword fixed_n_cols>
5787 arma_inline
5788 arma_warn_unused
5789 eT&
5790 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col)
5791 {
5792 arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::fixed::operator(): out of bounds");
5793
5794 const uword i = in_row + in_col*fixed_n_rows;
5795
5796 return access::rw( Mat<eT>::mem[i] );
5797 }
5798
5799
5800
5801 template<typename eT>
5802 template<uword fixed_n_rows, uword fixed_n_cols>
5803 arma_inline
5804 arma_warn_unused
5805 eT
5806 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::operator() (const uword in_row, const uword in_col) const
5807 {
5808 arma_debug_check( ((in_row >= fixed_n_rows) || (in_col >= fixed_n_cols)), "Mat::fixed::operator(): out of bounds");
5809
5810 const uword i = in_row + in_col*fixed_n_rows;
5811
5812 return ( Mat<eT>::mem[i] );
5813 }
5814
5815
5816
5817 template<typename eT>
5818 template<uword fixed_n_rows, uword fixed_n_cols>
5819 arma_hot
5820 inline
5821 const Mat<eT>&
5822 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fill(const eT val)
5823 {
5824 arma_extra_debug_sigprint();
5825
5826 arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), val, fixed_n_elem );
5827
5828 return *this;
5829 }
5830
5831
5832
5833 template<typename eT>
5834 template<uword fixed_n_rows, uword fixed_n_cols>
5835 arma_hot
5836 inline
5837 const Mat<eT>&
5838 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::zeros()
5839 {
5840 arma_extra_debug_sigprint();
5841
5842 arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(0), fixed_n_elem );
5843
5844 return *this;
5845 }
5846
5847
5848
5849 template<typename eT>
5850 template<uword fixed_n_rows, uword fixed_n_cols>
5851 arma_hot
5852 inline
5853 const Mat<eT>&
5854 Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::ones()
5855 {
5856 arma_extra_debug_sigprint();
5857
5858 arrayops::inplace_set( const_cast<eT*>(Mat<eT>::mem), eT(1), fixed_n_elem );
5859
5860 return *this;
5861 }
5862
5863
5864
5865 //! prefix ++
5866 template<typename eT>
5867 arma_inline
5868 void
5869 Mat_aux::prefix_pp(Mat<eT>& x)
5870 {
5871 eT* memptr = x.memptr();
5872 const uword n_elem = x.n_elem;
5873
5874 uword i,j;
5875
5876 for(i=0, j=1; j<n_elem; i+=2, j+=2)
5877 {
5878 ++(memptr[i]);
5879 ++(memptr[j]);
5880 }
5881
5882 if(i < n_elem)
5883 {
5884 ++(memptr[i]);
5885 }
5886 }
5887
5888
5889
5890 //! prefix ++ for complex numbers (work around for limitations of the std::complex class)
5891 template<typename T>
5892 arma_inline
5893 void
5894 Mat_aux::prefix_pp(Mat< std::complex<T> >& x)
5895 {
5896 x += T(1);
5897 }
5898
5899
5900
5901 //! postfix ++
5902 template<typename eT>
5903 arma_inline
5904 void
5905 Mat_aux::postfix_pp(Mat<eT>& x)
5906 {
5907 eT* memptr = x.memptr();
5908 const uword n_elem = x.n_elem;
5909
5910 uword i,j;
5911
5912 for(i=0, j=1; j<n_elem; i+=2, j+=2)
5913 {
5914 (memptr[i])++;
5915 (memptr[j])++;
5916 }
5917
5918 if(i < n_elem)
5919 {
5920 (memptr[i])++;
5921 }
5922 }
5923
5924
5925
5926 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
5927 template<typename T>
5928 arma_inline
5929 void
5930 Mat_aux::postfix_pp(Mat< std::complex<T> >& x)
5931 {
5932 x += T(1);
5933 }
5934
5935
5936
5937 //! prefix --
5938 template<typename eT>
5939 arma_inline
5940 void
5941 Mat_aux::prefix_mm(Mat<eT>& x)
5942 {
5943 eT* memptr = x.memptr();
5944 const uword n_elem = x.n_elem;
5945
5946 uword i,j;
5947
5948 for(i=0, j=1; j<n_elem; i+=2, j+=2)
5949 {
5950 --(memptr[i]);
5951 --(memptr[j]);
5952 }
5953
5954 if(i < n_elem)
5955 {
5956 --(memptr[i]);
5957 }
5958 }
5959
5960
5961
5962 //! prefix -- for complex numbers (work around for limitations of the std::complex class)
5963 template<typename T>
5964 arma_inline
5965 void
5966 Mat_aux::prefix_mm(Mat< std::complex<T> >& x)
5967 {
5968 x -= T(1);
5969 }
5970
5971
5972
5973 //! postfix --
5974 template<typename eT>
5975 arma_inline
5976 void
5977 Mat_aux::postfix_mm(Mat<eT>& x)
5978 {
5979 eT* memptr = x.memptr();
5980 const uword n_elem = x.n_elem;
5981
5982 uword i,j;
5983
5984 for(i=0, j=1; j<n_elem; i+=2, j+=2)
5985 {
5986 (memptr[i])--;
5987 (memptr[j])--;
5988 }
5989
5990 if(i < n_elem)
5991 {
5992 (memptr[i])--;
5993 }
5994 }
5995
5996
5997
5998 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
5999 template<typename T>
6000 arma_inline
6001 void
6002 Mat_aux::postfix_mm(Mat< std::complex<T> >& x)
6003 {
6004 x -= T(1);
6005 }
6006
6007
6008
6009 template<typename eT, typename T1>
6010 inline
6011 void
6012 Mat_aux::set_real(Mat<eT>& out, const Base<eT,T1>& X)
6013 {
6014 arma_extra_debug_sigprint();
6015
6016 const unwrap<T1> tmp(X.get_ref());
6017 const Mat<eT>& A = tmp.M;
6018
6019 arma_debug_assert_same_size( out, A, "Mat::set_real()" );
6020
6021 out = A;
6022 }
6023
6024
6025
6026 template<typename eT, typename T1>
6027 inline
6028 void
6029 Mat_aux::set_imag(Mat<eT>& out, const Base<eT,T1>& X)
6030 {
6031 arma_extra_debug_sigprint();
6032 }
6033
6034
6035
6036 template<typename T, typename T1>
6037 inline
6038 void
6039 Mat_aux::set_real(Mat< std::complex<T> >& out, const Base<T,T1>& X)
6040 {
6041 arma_extra_debug_sigprint();
6042
6043 typedef typename std::complex<T> eT;
6044 typedef typename Proxy<T1>::ea_type ea_type;
6045
6046 const Proxy<T1> A(X.get_ref());
6047
6048 arma_debug_assert_same_size( out, A, "Mat::set_real()" );
6049
6050 const uword n_elem = out.n_elem;
6051 eT* out_mem = out.memptr();
6052 ea_type PA = A.get_ea();
6053
6054 for(uword i=0; i<n_elem; ++i)
6055 {
6056 //out_mem[i].real() = PA[i];
6057 out_mem[i] = std::complex<T>( PA[i], out_mem[i].imag() );
6058 }
6059 }
6060
6061
6062
6063 template<typename T, typename T1>
6064 inline
6065 void
6066 Mat_aux::set_imag(Mat< std::complex<T> >& out, const Base<T,T1>& X)
6067 {
6068 arma_extra_debug_sigprint();
6069
6070 typedef typename std::complex<T> eT;
6071 typedef typename Proxy<T1>::ea_type ea_type;
6072
6073 const Proxy<T1> A(X.get_ref());
6074
6075 arma_debug_assert_same_size( out, A, "Mat::set_imag()" );
6076
6077 const uword n_elem = out.n_elem;
6078 eT* out_mem = out.memptr();
6079 ea_type PA = A.get_ea();
6080
6081 for(uword i=0; i<n_elem; ++i)
6082 {
6083 //out_mem[i].imag() = PA[i];
6084 out_mem[i] = std::complex<T>( out_mem[i].real(), PA[i] );
6085 }
6086 }
6087
6088
6089
6090 #ifdef ARMA_EXTRA_MAT_MEAT
6091 #include ARMA_INCFILE_WRAP(ARMA_EXTRA_MAT_MEAT)
6092 #endif
6093
6094
6095
6096 //! @}