comparison armadillo-3.900.4/include/armadillo_bits/Mat_meat.hpp @ 49:1ec0e2823891

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