00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00016
00017
00018 template<typename eT>
00019 inline
00020 Cube<eT>::~Cube()
00021 {
00022 arma_extra_debug_sigprint_this(this);
00023
00024 delete_mat();
00025
00026 if(mem_state == 0)
00027 {
00028 if(n_elem > Cube_prealloc::mem_n_elem)
00029 {
00030 #if defined(ARMA_USE_TBB_ALLOC)
00031 scalable_free((void *)(mem));
00032 #else
00033 delete [] mem;
00034 #endif
00035 }
00036 }
00037
00038 if(arma_config::debug == true)
00039 {
00040
00041 access::rw(n_rows) = 0;
00042 access::rw(n_cols) = 0;
00043 access::rw(n_slices) = 0;
00044 access::rw(n_elem) = 0;
00045 access::rw(mat_ptrs) = 0;
00046 access::rw(mem) = 0;
00047 }
00048
00049 arma_type_check(( is_supported_elem_type<eT>::value == false ));
00050 }
00051
00052
00053
00054 template<typename eT>
00055 inline
00056 Cube<eT>::Cube()
00057 : n_rows(0)
00058 , n_cols(0)
00059 , n_elem_slice(0)
00060 , n_slices(0)
00061 , n_elem(0)
00062 , mem_state(0)
00063 , mat_ptrs()
00064 , mem()
00065 {
00066 arma_extra_debug_sigprint_this(this);
00067 }
00068
00069
00070
00072 template<typename eT>
00073 inline
00074 Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
00075 : n_rows(in_n_rows)
00076 , n_cols(in_n_cols)
00077 , n_elem_slice(in_n_rows*in_n_cols)
00078 , n_slices(in_n_slices)
00079 , n_elem(in_n_rows*in_n_cols*in_n_slices)
00080 , mem_state(0)
00081 , mat_ptrs()
00082 , mem()
00083 {
00084 arma_extra_debug_sigprint_this(this);
00085
00086 init_cold();
00087 }
00088
00089
00090
00091 template<typename eT>
00092 inline
00093 void
00094 Cube<eT>::init_cold()
00095 {
00096 arma_extra_debug_sigprint( arma_boost::format("n_rows = %d, n_cols = %d, n_slices = %d") % n_rows % n_cols % n_slices );
00097
00098 arma_debug_check
00099 (
00100 (
00101 ( (n_rows > 0x0FFF) || (n_cols > 0x0FFF) || (n_slices > 0xFF) )
00102 ? ( (float(n_rows) * float(n_cols) * float(n_slices)) > float(ARMA_MAX_UWORD) )
00103 : false
00104 ),
00105 "Cube::init(): requested size is too large"
00106 );
00107
00108 if(n_elem <= Cube_prealloc::mem_n_elem)
00109 {
00110 access::rw(mem) = mem_local;
00111 }
00112 else
00113 {
00114 arma_extra_debug_print("Cube::init(): allocating memory");
00115
00116 #if defined(ARMA_USE_TBB_ALLOC)
00117 access::rw(mem) = (eT *)scalable_malloc(sizeof(eT)*n_elem);
00118 #else
00119 access::rw(mem) = new(std::nothrow) eT[n_elem];
00120 #endif
00121
00122 arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" );
00123 }
00124
00125
00126 if(n_elem == 0)
00127 {
00128 access::rw(n_rows) = 0;
00129 access::rw(n_cols) = 0;
00130 access::rw(n_elem_slice) = 0;
00131 access::rw(n_slices) = 0;
00132 }
00133 else
00134 {
00135 create_mat();
00136 }
00137 }
00138
00139
00140
00143 template<typename eT>
00144 inline
00145 void
00146 Cube<eT>::init_warm(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
00147 {
00148 arma_extra_debug_sigprint( arma_boost::format("in_n_rows = %d, in_n_cols = %d, in_n_slices = %d") % in_n_rows % in_n_cols % in_n_slices );
00149
00150 if( (n_rows == in_n_rows) && (n_cols == in_n_cols) && (n_slices == in_n_slices) )
00151 {
00152 return;
00153 }
00154
00155 const uword t_mem_state = mem_state;
00156
00157 bool err_state = false;
00158 char* err_msg = 0;
00159
00160 arma_debug_set_error
00161 (
00162 err_state,
00163 err_msg,
00164 (t_mem_state == 3),
00165 "Cube::init(): size is fixed and hence cannot be changed"
00166 );
00167
00168 arma_debug_set_error
00169 (
00170 err_state,
00171 err_msg,
00172 (
00173 ( (in_n_rows > 0x0FFF) || (in_n_cols > 0x0FFF) || (in_n_slices > 0xFF) )
00174 ? ( (float(in_n_rows) * float(in_n_cols) * float(in_n_slices)) > float(ARMA_MAX_UWORD) )
00175 : false
00176 ),
00177 "Cube::init(): requested size is too large"
00178 );
00179
00180 arma_debug_check(err_state, err_msg);
00181
00182 const uword old_n_elem = n_elem;
00183 const uword new_n_elem = in_n_rows * in_n_cols * in_n_slices;
00184
00185 if(old_n_elem == new_n_elem)
00186 {
00187 delete_mat();
00188
00189 if(new_n_elem > 0)
00190 {
00191 access::rw(n_rows) = in_n_rows;
00192 access::rw(n_cols) = in_n_cols;
00193 access::rw(n_elem_slice) = in_n_rows*in_n_cols;
00194 access::rw(n_slices) = in_n_slices;
00195
00196 create_mat();
00197 }
00198 }
00199 else
00200 {
00201 arma_debug_check( (t_mem_state == 2), "Cube::init(): requested size is not compatible with the size of auxiliary memory" );
00202
00203 delete_mat();
00204
00205 if(t_mem_state == 0)
00206 {
00207 if(n_elem > Cube_prealloc::mem_n_elem )
00208 {
00209 arma_extra_debug_print("Cube::init(): freeing memory");
00210
00211 #if defined(ARMA_USE_TBB_ALLOC)
00212 scalable_free((void *)(mem));
00213 #else
00214 delete [] mem;
00215 #endif
00216 }
00217 }
00218
00219 access::rw(mem_state) = 0;
00220
00221 if(new_n_elem <= Cube_prealloc::mem_n_elem)
00222 {
00223 access::rw(mem) = mem_local;
00224 }
00225 else
00226 {
00227 arma_extra_debug_print("Cube::init(): allocating memory");
00228
00229 #if defined(ARMA_USE_TBB_ALLOC)
00230 access::rw(mem) = (eT *)scalable_malloc(sizeof(eT)*new_n_elem);
00231 #else
00232 access::rw(mem) = new(std::nothrow) eT[new_n_elem];
00233 #endif
00234
00235 arma_check_bad_alloc( (mem == 0), "Cube::init(): out of memory" );
00236 }
00237
00238 if(new_n_elem > 0)
00239 {
00240 access::rw(n_rows) = in_n_rows;
00241 access::rw(n_cols) = in_n_cols;
00242 access::rw(n_elem_slice) = in_n_rows*in_n_cols;
00243 access::rw(n_slices) = in_n_slices;
00244 access::rw(n_elem) = new_n_elem;
00245
00246 create_mat();
00247 }
00248 }
00249
00250
00251 if(new_n_elem == 0)
00252 {
00253 access::rw(n_rows) = 0;
00254 access::rw(n_cols) = 0;
00255 access::rw(n_elem_slice) = 0;
00256 access::rw(n_slices) = 0;
00257 access::rw(n_elem) = 0;
00258 }
00259 }
00260
00261
00262
00264 template<typename eT>
00265 template<typename T1, typename T2>
00266 inline
00267 void
00268 Cube<eT>::init
00269 (
00270 const BaseCube<typename Cube<eT>::pod_type,T1>& A,
00271 const BaseCube<typename Cube<eT>::pod_type,T2>& B
00272 )
00273 {
00274 arma_extra_debug_sigprint();
00275
00276 typedef typename T1::elem_type T;
00277 typedef typename ProxyCube<T1>::ea_type ea_type1;
00278 typedef typename ProxyCube<T2>::ea_type ea_type2;
00279
00280 arma_type_check(( is_complex<eT>::value == false ));
00281 arma_type_check(( is_complex< T>::value == true ));
00282
00283 arma_type_check(( is_same_type< std::complex<T>, eT >::value == false ));
00284
00285 const ProxyCube<T1> X(A.get_ref());
00286 const ProxyCube<T2> Y(B.get_ref());
00287
00288 arma_assert_same_size(X, Y, "Cube()");
00289
00290 init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
00291
00292 const uword N = n_elem;
00293 eT* out_mem = memptr();
00294 ea_type1 PX = X.get_ea();
00295 ea_type2 PY = Y.get_ea();
00296
00297 for(uword i=0; i<N; ++i)
00298 {
00299 out_mem[i] = std::complex<T>(PX[i], PY[i]);
00300 }
00301 }
00302
00303
00304
00307 template<typename eT>
00308 inline
00309 void
00310 Cube<eT>::steal_mem(Cube<eT>& x)
00311 {
00312 arma_extra_debug_sigprint();
00313
00314 if(this != &x)
00315 {
00316 if( (x.mem_state == 0) && (x.n_elem > Cube_prealloc::mem_n_elem) )
00317 {
00318 reset();
00319
00320 const uword x_n_slices = x.n_slices;
00321
00322 access::rw(n_rows) = x.n_rows;
00323 access::rw(n_cols) = x.n_cols;
00324 access::rw(n_elem_slice) = x.n_elem_slice;
00325 access::rw(n_slices) = x_n_slices;
00326 access::rw(n_elem) = x.n_elem;
00327 access::rw(mem) = x.mem;
00328
00329 if(x_n_slices > Cube_prealloc::mat_ptrs_size)
00330 {
00331 access::rw( mat_ptrs) = x.mat_ptrs;
00332 access::rw(x.mat_ptrs) = 0;
00333 }
00334 else
00335 {
00336 access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
00337
00338 for(uword i=0; i < x_n_slices; ++i)
00339 {
00340 mat_ptrs[i] = x.mat_ptrs[i];
00341 x.mat_ptrs[i] = 0;
00342 }
00343 }
00344
00345 access::rw(x.n_rows) = 0;
00346 access::rw(x.n_cols) = 0;
00347 access::rw(x.n_elem_slice) = 0;
00348 access::rw(x.n_slices) = 0;
00349 access::rw(x.n_elem) = 0;
00350 access::rw(x.mem) = 0;
00351 }
00352 else
00353 {
00354 (*this).operator=(x);
00355 }
00356 }
00357 }
00358
00359
00360
00361 template<typename eT>
00362 inline
00363 void
00364 Cube<eT>::delete_mat()
00365 {
00366 arma_extra_debug_sigprint();
00367
00368 for(uword slice = 0; slice < n_slices; ++slice)
00369 {
00370 delete access::rw(mat_ptrs[slice]);
00371 }
00372
00373 if(mem_state <= 2)
00374 {
00375 if(n_slices > Cube_prealloc::mat_ptrs_size)
00376 {
00377 delete [] mat_ptrs;
00378 }
00379 }
00380 }
00381
00382
00383
00384 template<typename eT>
00385 inline
00386 void
00387 Cube<eT>::create_mat()
00388 {
00389 arma_extra_debug_sigprint();
00390
00391 if(mem_state <= 2)
00392 {
00393 if(n_slices <= Cube_prealloc::mat_ptrs_size)
00394 {
00395 access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
00396 }
00397 else
00398 {
00399 access::rw(mat_ptrs) = new(std::nothrow) const Mat<eT>*[n_slices];
00400
00401 arma_check_bad_alloc( (mat_ptrs == 0), "Cube::create_mat(): out of memory" );
00402 }
00403 }
00404
00405 for(uword slice = 0; slice < n_slices; ++slice)
00406 {
00407 mat_ptrs[slice] = new Mat<eT>('j', slice_memptr(slice), n_rows, n_cols);
00408 }
00409 }
00410
00411
00412
00415 template<typename eT>
00416 arma_inline
00417 const Cube<eT>&
00418 Cube<eT>::operator=(const eT val)
00419 {
00420 arma_extra_debug_sigprint();
00421
00422 init_warm(1,1,1);
00423 access::rw(mem[0]) = val;
00424 return *this;
00425 }
00426
00427
00428
00430 template<typename eT>
00431 arma_inline
00432 const Cube<eT>&
00433 Cube<eT>::operator+=(const eT val)
00434 {
00435 arma_extra_debug_sigprint();
00436
00437 arrayops::inplace_plus( memptr(), val, n_elem );
00438
00439 return *this;
00440 }
00441
00442
00443
00445 template<typename eT>
00446 arma_inline
00447 const Cube<eT>&
00448 Cube<eT>::operator-=(const eT val)
00449 {
00450 arma_extra_debug_sigprint();
00451
00452 arrayops::inplace_minus( memptr(), val, n_elem );
00453
00454 return *this;
00455 }
00456
00457
00458
00460 template<typename eT>
00461 arma_inline
00462 const Cube<eT>&
00463 Cube<eT>::operator*=(const eT val)
00464 {
00465 arma_extra_debug_sigprint();
00466
00467 arrayops::inplace_mul( memptr(), val, n_elem );
00468
00469 return *this;
00470 }
00471
00472
00473
00475 template<typename eT>
00476 arma_inline
00477 const Cube<eT>&
00478 Cube<eT>::operator/=(const eT val)
00479 {
00480 arma_extra_debug_sigprint();
00481
00482 arrayops::inplace_div( memptr(), val, n_elem );
00483
00484 return *this;
00485 }
00486
00487
00488
00490 template<typename eT>
00491 inline
00492 Cube<eT>::Cube(const Cube<eT>& x)
00493 : n_rows(x.n_rows)
00494 , n_cols(x.n_cols)
00495 , n_elem_slice(x.n_elem_slice)
00496 , n_slices(x.n_slices)
00497 , n_elem(x.n_elem)
00498 , mem_state(0)
00499 , mat_ptrs()
00500 , mem()
00501 {
00502 arma_extra_debug_sigprint_this(this);
00503 arma_extra_debug_sigprint(arma_boost::format("this = %x in_cube = %x") % this % &x);
00504
00505 init_cold();
00506
00507 arrayops::copy( memptr(), x.mem, n_elem );
00508 }
00509
00510
00511
00513 template<typename eT>
00514 inline
00515 const Cube<eT>&
00516 Cube<eT>::operator=(const Cube<eT>& x)
00517 {
00518 arma_extra_debug_sigprint(arma_boost::format("this = %x in_cube = %x") % this % &x);
00519
00520 if(this != &x)
00521 {
00522 init_warm(x.n_rows, x.n_cols, x.n_slices);
00523
00524 arrayops::copy( memptr(), x.mem, n_elem );
00525 }
00526
00527 return *this;
00528 }
00529
00530
00531
00537
00538 template<typename eT>
00539 inline
00540 Cube<eT>::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices, const bool copy_aux_mem, const bool strict)
00541 : n_rows ( aux_n_rows )
00542 , n_cols ( aux_n_cols )
00543 , n_elem_slice( aux_n_rows*aux_n_cols )
00544 , n_slices ( aux_n_slices )
00545 , n_elem ( aux_n_rows*aux_n_cols*aux_n_slices )
00546 , mem_state ( copy_aux_mem ? 0 : (strict ? 2 : 1) )
00547 , mat_ptrs ( 0 )
00548 , mem ( copy_aux_mem ? 0 : aux_mem )
00549 {
00550 arma_extra_debug_sigprint_this(this);
00551
00552 if(copy_aux_mem == true)
00553 {
00554 init_cold();
00555
00556 arrayops::copy( memptr(), aux_mem, n_elem );
00557 }
00558 else
00559 {
00560 create_mat();
00561 }
00562 }
00563
00564
00565
00568 template<typename eT>
00569 inline
00570 Cube<eT>::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const uword aux_n_slices)
00571 : n_rows(aux_n_rows)
00572 , n_cols(aux_n_cols)
00573 , n_elem_slice(aux_n_rows*aux_n_cols)
00574 , n_slices(aux_n_slices)
00575 , n_elem(aux_n_rows*aux_n_cols*aux_n_slices)
00576 , mem_state(0)
00577 , mat_ptrs()
00578 , mem()
00579 {
00580 arma_extra_debug_sigprint_this(this);
00581
00582 init_cold();
00583
00584 arrayops::copy( memptr(), aux_mem, n_elem );
00585 }
00586
00587
00588
00590 template<typename eT>
00591 inline
00592 const Cube<eT>&
00593 Cube<eT>::operator+=(const Cube<eT>& m)
00594 {
00595 arma_extra_debug_sigprint();
00596
00597 arma_debug_assert_same_size(*this, m, "cube addition");
00598
00599 arrayops::inplace_plus( memptr(), m.memptr(), n_elem );
00600
00601 return *this;
00602 }
00603
00604
00605
00607 template<typename eT>
00608 inline
00609 const Cube<eT>&
00610 Cube<eT>::operator-=(const Cube<eT>& m)
00611 {
00612 arma_extra_debug_sigprint();
00613
00614 arma_debug_assert_same_size(*this, m, "cube subtraction");
00615
00616 arrayops::inplace_minus( memptr(), m.memptr(), n_elem );
00617
00618 return *this;
00619 }
00620
00621
00622
00624 template<typename eT>
00625 inline
00626 const Cube<eT>&
00627 Cube<eT>::operator%=(const Cube<eT>& m)
00628 {
00629 arma_extra_debug_sigprint();
00630
00631 arma_debug_assert_same_size(*this, m, "element-wise cube multiplication");
00632
00633 arrayops::inplace_mul( memptr(), m.memptr(), n_elem );
00634
00635 return *this;
00636 }
00637
00638
00639
00641 template<typename eT>
00642 inline
00643 const Cube<eT>&
00644 Cube<eT>::operator/=(const Cube<eT>& m)
00645 {
00646 arma_extra_debug_sigprint();
00647
00648 arma_debug_assert_same_size(*this, m, "element-wise cube division");
00649
00650 arrayops::inplace_div( memptr(), m.memptr(), n_elem );
00651
00652 return *this;
00653 }
00654
00655
00656
00658 template<typename eT>
00659 template<typename T1, typename T2>
00660 inline
00661 Cube<eT>::Cube
00662 (
00663 const BaseCube<typename Cube<eT>::pod_type,T1>& A,
00664 const BaseCube<typename Cube<eT>::pod_type,T2>& B
00665 )
00666 : n_rows(0)
00667 , n_cols(0)
00668 , n_elem_slice(0)
00669 , n_slices(0)
00670 , n_elem(0)
00671 , mem_state(0)
00672 , mat_ptrs()
00673 , mem()
00674 {
00675 arma_extra_debug_sigprint_this(this);
00676
00677 init(A,B);
00678 }
00679
00680
00681
00683 template<typename eT>
00684 inline
00685 Cube<eT>::Cube(const subview_cube<eT>& X)
00686 : n_rows(X.n_rows)
00687 , n_cols(X.n_cols)
00688 , n_elem_slice(X.n_elem_slice)
00689 , n_slices(X.n_slices)
00690 , n_elem(X.n_elem)
00691 , mem_state(0)
00692 , mat_ptrs()
00693 , mem()
00694 {
00695 arma_extra_debug_sigprint_this(this);
00696
00697 init_cold();
00698
00699 subview_cube<eT>::extract(*this, X);
00700 }
00701
00702
00703
00705 template<typename eT>
00706 inline
00707 const Cube<eT>&
00708 Cube<eT>::operator=(const subview_cube<eT>& X)
00709 {
00710 arma_extra_debug_sigprint();
00711
00712 const bool alias = (this == &(X.m));
00713
00714 if(alias == false)
00715 {
00716 init_warm(X.n_rows, X.n_cols, X.n_slices);
00717
00718 subview_cube<eT>::extract(*this, X);
00719 }
00720 else
00721 {
00722 Cube<eT> tmp(X);
00723
00724 steal_mem(tmp);
00725 }
00726
00727 return *this;
00728 }
00729
00730
00731
00733 template<typename eT>
00734 inline
00735 const Cube<eT>&
00736 Cube<eT>::operator+=(const subview_cube<eT>& X)
00737 {
00738 arma_extra_debug_sigprint();
00739
00740 subview_cube<eT>::plus_inplace(*this, X);
00741
00742 return *this;
00743 }
00744
00745
00746
00748 template<typename eT>
00749 inline
00750 const Cube<eT>&
00751 Cube<eT>::operator-=(const subview_cube<eT>& X)
00752 {
00753 arma_extra_debug_sigprint();
00754
00755 subview_cube<eT>::minus_inplace(*this, X);
00756
00757 return *this;
00758 }
00759
00760
00761
00763 template<typename eT>
00764 inline
00765 const Cube<eT>&
00766 Cube<eT>::operator%=(const subview_cube<eT>& X)
00767 {
00768 arma_extra_debug_sigprint();
00769
00770 subview_cube<eT>::schur_inplace(*this, X);
00771
00772 return *this;
00773 }
00774
00775
00776
00778 template<typename eT>
00779 inline
00780 const Cube<eT>&
00781 Cube<eT>::operator/=(const subview_cube<eT>& X)
00782 {
00783 arma_extra_debug_sigprint();
00784
00785 subview_cube<eT>::div_inplace(*this, X);
00786
00787 return *this;
00788 }
00789
00790
00791
00793 template<typename eT>
00794 arma_inline
00795 Mat<eT>&
00796 Cube<eT>::slice(const uword in_slice)
00797 {
00798 arma_extra_debug_sigprint();
00799
00800 arma_debug_check
00801 (
00802 (in_slice >= n_slices),
00803 "Cube::slice(): index out of bounds"
00804 );
00805
00806 return const_cast< Mat<eT>& >( *(mat_ptrs[in_slice]) );
00807 }
00808
00809
00810
00812 template<typename eT>
00813 arma_inline
00814 const Mat<eT>&
00815 Cube<eT>::slice(const uword in_slice) const
00816 {
00817 arma_extra_debug_sigprint();
00818
00819 arma_debug_check
00820 (
00821 (in_slice >= n_slices),
00822 "Cube::slice(): index out of bounds"
00823 );
00824
00825 return *(mat_ptrs[in_slice]);
00826 }
00827
00828
00829
00831 template<typename eT>
00832 arma_inline
00833 subview_cube<eT>
00834 Cube<eT>::slices(const uword in_slice1, const uword in_slice2)
00835 {
00836 arma_extra_debug_sigprint();
00837
00838 arma_debug_check
00839 (
00840 (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
00841 "Cube::slices(): indices out of bounds or incorrectly used"
00842 );
00843
00844 const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
00845
00846 return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices);
00847 }
00848
00849
00850
00852 template<typename eT>
00853 arma_inline
00854 const subview_cube<eT>
00855 Cube<eT>::slices(const uword in_slice1, const uword in_slice2) const
00856 {
00857 arma_extra_debug_sigprint();
00858
00859 arma_debug_check
00860 (
00861 (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
00862 "Cube::rows(): indices out of bounds or incorrectly used"
00863 );
00864
00865 const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
00866
00867 return subview_cube<eT>(*this, 0, 0, in_slice1, n_rows, n_cols, subcube_n_slices);
00868 }
00869
00870
00871
00873 template<typename eT>
00874 arma_inline
00875 subview_cube<eT>
00876 Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2)
00877 {
00878 arma_extra_debug_sigprint();
00879
00880 arma_debug_check
00881 (
00882 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) ||
00883 (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices),
00884 "Cube::subcube(): indices out of bounds or incorrectly used"
00885 );
00886
00887 const uword subcube_n_rows = in_row2 - in_row1 + 1;
00888 const uword subcube_n_cols = in_col2 - in_col1 + 1;
00889 const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
00890
00891 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
00892 }
00893
00894
00895
00897 template<typename eT>
00898 arma_inline
00899 const subview_cube<eT>
00900 Cube<eT>::subcube(const uword in_row1, const uword in_col1, const uword in_slice1, const uword in_row2, const uword in_col2, const uword in_slice2) const
00901 {
00902 arma_extra_debug_sigprint();
00903
00904 arma_debug_check
00905 (
00906 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_slice1 > in_slice2) ||
00907 (in_row2 >= n_rows) || (in_col2 >= n_cols) || (in_slice2 >= n_slices),
00908 "Cube::subcube(): indices out of bounds or incorrectly used"
00909 );
00910
00911 const uword subcube_n_rows = in_row2 - in_row1 + 1;
00912 const uword subcube_n_cols = in_col2 - in_col1 + 1;
00913 const uword subcube_n_slices = in_slice2 - in_slice1 + 1;
00914
00915 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
00916 }
00917
00918
00919
00921 template<typename eT>
00922 inline
00923 subview_cube<eT>
00924 Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span)
00925 {
00926 arma_extra_debug_sigprint();
00927
00928 const bool row_all = row_span.whole;
00929 const bool col_all = col_span.whole;
00930 const bool slice_all = slice_span.whole;
00931
00932 const uword local_n_rows = n_rows;
00933 const uword local_n_cols = n_cols;
00934 const uword local_n_slices = n_slices;
00935
00936 const uword in_row1 = row_all ? 0 : row_span.a;
00937 const uword in_row2 = row_span.b;
00938 const uword subcube_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
00939
00940 const uword in_col1 = col_all ? 0 : col_span.a;
00941 const uword in_col2 = col_span.b;
00942 const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
00943
00944 const uword in_slice1 = slice_all ? 0 : slice_span.a;
00945 const uword in_slice2 = slice_span.b;
00946 const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1;
00947
00948 arma_debug_check
00949 (
00950 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
00951 ||
00952 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
00953 ||
00954 ( slice_all ? false : ((in_slice1 > in_slice2) || (in_slice2 >= local_n_slices)) )
00955 ,
00956 "Cube::subcube(): indices out of bounds or incorrectly used"
00957 );
00958
00959 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
00960 }
00961
00962
00963
00965 template<typename eT>
00966 inline
00967 const subview_cube<eT>
00968 Cube<eT>::subcube(const span& row_span, const span& col_span, const span& slice_span) const
00969 {
00970 arma_extra_debug_sigprint();
00971
00972 const bool row_all = row_span.whole;
00973 const bool col_all = col_span.whole;
00974 const bool slice_all = slice_span.whole;
00975
00976 const uword local_n_rows = n_rows;
00977 const uword local_n_cols = n_cols;
00978 const uword local_n_slices = n_slices;
00979
00980 const uword in_row1 = row_all ? 0 : row_span.a;
00981 const uword in_row2 = row_span.b;
00982 const uword subcube_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
00983
00984 const uword in_col1 = col_all ? 0 : col_span.a;
00985 const uword in_col2 = col_span.b;
00986 const uword subcube_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
00987
00988 const uword in_slice1 = slice_all ? 0 : slice_span.a;
00989 const uword in_slice2 = slice_span.b;
00990 const uword subcube_n_slices = slice_all ? local_n_slices : in_slice2 - in_slice1 + 1;
00991
00992 arma_debug_check
00993 (
00994 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
00995 ||
00996 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
00997 ||
00998 ( slice_all ? false : ((in_slice1 > in_slice2) || (in_slice2 >= local_n_slices)) )
00999 ,
01000 "Cube::subcube(): indices out of bounds or incorrectly used"
01001 );
01002
01003 return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, subcube_n_rows, subcube_n_cols, subcube_n_slices);
01004 }
01005
01006
01007
01008 template<typename eT>
01009 inline
01010 subview_cube<eT>
01011 Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span)
01012 {
01013 arma_extra_debug_sigprint();
01014
01015 return (*this).subcube(row_span, col_span, slice_span);
01016 }
01017
01018
01019
01020 template<typename eT>
01021 inline
01022 const subview_cube<eT>
01023 Cube<eT>::operator()(const span& row_span, const span& col_span, const span& slice_span) const
01024 {
01025 arma_extra_debug_sigprint();
01026
01027 return (*this).subcube(row_span, col_span, slice_span);
01028 }
01029
01030
01031
01033 template<typename eT>
01034 inline
01035 void
01036 Cube<eT>::shed_slice(const uword slice_num)
01037 {
01038 arma_extra_debug_sigprint();
01039
01040 arma_debug_check( slice_num >= n_slices, "Cube::shed_slice(): out of bounds");
01041
01042 shed_slices(slice_num, slice_num);
01043 }
01044
01045
01046
01048 template<typename eT>
01049 inline
01050 void
01051 Cube<eT>::shed_slices(const uword in_slice1, const uword in_slice2)
01052 {
01053 arma_extra_debug_sigprint();
01054
01055 arma_debug_check
01056 (
01057 (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
01058 "Cube::shed_slices(): indices out of bounds or incorrectly used"
01059 );
01060
01061 const uword n_keep_front = in_slice1;
01062 const uword n_keep_back = n_slices - (in_slice2 + 1);
01063
01064 Cube<eT> X(n_rows, n_cols, n_keep_front + n_keep_back);
01065
01066 if(n_keep_front > 0)
01067 {
01068 X.slices( 0, (n_keep_front-1) ) = slices( 0, (in_slice1-1) );
01069 }
01070
01071 if(n_keep_back > 0)
01072 {
01073 X.slices( n_keep_front, (n_keep_front+n_keep_back-1) ) = slices( (in_slice2+1), (n_slices-1) );
01074 }
01075
01076 steal_mem(X);
01077 }
01078
01079
01080
01083 template<typename eT>
01084 inline
01085 void
01086 Cube<eT>::insert_slices(const uword slice_num, const uword N, const bool set_to_zero)
01087 {
01088 arma_extra_debug_sigprint();
01089
01090 const uword t_n_slices = n_slices;
01091
01092 const uword A_n_slices = slice_num;
01093 const uword B_n_slices = t_n_slices - slice_num;
01094
01095
01096 arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): out of bounds");
01097
01098 if(N > 0)
01099 {
01100 Cube<eT> out(n_rows, n_cols, t_n_slices + N);
01101
01102 if(A_n_slices > 0)
01103 {
01104 out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1);
01105 }
01106
01107 if(B_n_slices > 0)
01108 {
01109 out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices-1);
01110 }
01111
01112 if(set_to_zero == true)
01113 {
01114
01115
01116 for(uword i=slice_num; i < (slice_num + N); ++i)
01117 {
01118 out.slice(i).zeros();
01119 }
01120 }
01121
01122 steal_mem(out);
01123 }
01124 }
01125
01126
01127
01130 template<typename eT>
01131 template<typename T1>
01132 inline
01133 void
01134 Cube<eT>::insert_slices(const uword slice_num, const BaseCube<eT,T1>& X)
01135 {
01136 arma_extra_debug_sigprint();
01137
01138 const unwrap_cube<T1> tmp(X.get_ref());
01139 const Cube<eT>& C = tmp.M;
01140
01141 const uword N = C.n_slices;
01142
01143 const uword t_n_slices = n_slices;
01144
01145 const uword A_n_slices = slice_num;
01146 const uword B_n_slices = t_n_slices - slice_num;
01147
01148
01149 arma_debug_check( (slice_num > t_n_slices), "Cube::insert_slices(): out of bounds");
01150
01151 arma_debug_check
01152 (
01153 ( (C.n_rows != n_rows) || (C.n_cols != n_cols) ),
01154 "Cube::insert_slices(): given object has an incompatible dimensions"
01155 );
01156
01157 if(N > 0)
01158 {
01159 Cube<eT> out(n_rows, n_cols, t_n_slices + N);
01160
01161 if(A_n_slices > 0)
01162 {
01163 out.slices(0, A_n_slices-1) = slices(0, A_n_slices-1);
01164 }
01165
01166 if(B_n_slices > 0)
01167 {
01168 out.slices(slice_num + N, t_n_slices + N - 1) = slices(slice_num, t_n_slices - 1);
01169 }
01170
01171 out.slices(slice_num, slice_num + N - 1) = C;
01172
01173 steal_mem(out);
01174 }
01175 }
01176
01177
01178
01180 template<typename eT>
01181 template<typename gen_type>
01182 inline
01183 Cube<eT>::Cube(const GenCube<eT, gen_type>& X)
01184 : n_rows(X.n_rows)
01185 , n_cols(X.n_cols)
01186 , n_elem_slice(X.n_rows*X.n_cols)
01187 , n_slices(X.n_slices)
01188 , n_elem(X.n_rows*X.n_cols*X.n_slices)
01189 , mem_state(0)
01190 , mat_ptrs()
01191 , mem()
01192 {
01193 arma_extra_debug_sigprint_this(this);
01194
01195 init_cold();
01196
01197 X.apply(*this);
01198 }
01199
01200
01201
01202 template<typename eT>
01203 template<typename gen_type>
01204 inline
01205 const Cube<eT>&
01206 Cube<eT>::operator=(const GenCube<eT, gen_type>& X)
01207 {
01208 arma_extra_debug_sigprint();
01209
01210 init_warm(X.n_rows, X.n_cols, X.n_slices);
01211
01212 X.apply(*this);
01213
01214 return *this;
01215 }
01216
01217
01218
01219 template<typename eT>
01220 template<typename gen_type>
01221 inline
01222 const Cube<eT>&
01223 Cube<eT>::operator+=(const GenCube<eT, gen_type>& X)
01224 {
01225 arma_extra_debug_sigprint();
01226
01227 X.apply_inplace_plus(*this);
01228
01229 return *this;
01230 }
01231
01232
01233
01234 template<typename eT>
01235 template<typename gen_type>
01236 inline
01237 const Cube<eT>&
01238 Cube<eT>::operator-=(const GenCube<eT, gen_type>& X)
01239 {
01240 arma_extra_debug_sigprint();
01241
01242 X.apply_inplace_minus(*this);
01243
01244 return *this;
01245 }
01246
01247
01248
01249 template<typename eT>
01250 template<typename gen_type>
01251 inline
01252 const Cube<eT>&
01253 Cube<eT>::operator%=(const GenCube<eT, gen_type>& X)
01254 {
01255 arma_extra_debug_sigprint();
01256
01257 X.apply_inplace_schur(*this);
01258
01259 return *this;
01260 }
01261
01262
01263
01264 template<typename eT>
01265 template<typename gen_type>
01266 inline
01267 const Cube<eT>&
01268 Cube<eT>::operator/=(const GenCube<eT, gen_type>& X)
01269 {
01270 arma_extra_debug_sigprint();
01271
01272 X.apply_inplace_div(*this);
01273
01274 return *this;
01275 }
01276
01277
01278
01280 template<typename eT>
01281 template<typename T1, typename op_type>
01282 inline
01283 Cube<eT>::Cube(const OpCube<T1, op_type>& X)
01284 : n_rows(0)
01285 , n_cols(0)
01286 , n_elem_slice(0)
01287 , n_slices(0)
01288 , n_elem(0)
01289 , mem_state(0)
01290 , mat_ptrs()
01291 , mem()
01292 {
01293 arma_extra_debug_sigprint_this(this);
01294
01295 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01296
01297 op_type::apply(*this, X);
01298 }
01299
01300
01301
01303 template<typename eT>
01304 template<typename T1, typename op_type>
01305 inline
01306 const Cube<eT>&
01307 Cube<eT>::operator=(const OpCube<T1, op_type>& X)
01308 {
01309 arma_extra_debug_sigprint();
01310
01311 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01312
01313 op_type::apply(*this, X);
01314
01315 return *this;
01316 }
01317
01318
01319
01321 template<typename eT>
01322 template<typename T1, typename op_type>
01323 inline
01324 const Cube<eT>&
01325 Cube<eT>::operator+=(const OpCube<T1, op_type>& X)
01326 {
01327 arma_extra_debug_sigprint();
01328
01329 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01330
01331 const Cube<eT> m(X);
01332
01333 return (*this).operator+=(m);
01334 }
01335
01336
01337
01339 template<typename eT>
01340 template<typename T1, typename op_type>
01341 inline
01342 const Cube<eT>&
01343 Cube<eT>::operator-=(const OpCube<T1, op_type>& X)
01344 {
01345 arma_extra_debug_sigprint();
01346
01347 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01348
01349 const Cube<eT> m(X);
01350
01351 return (*this).operator-=(m);
01352 }
01353
01354
01355
01357 template<typename eT>
01358 template<typename T1, typename op_type>
01359 inline
01360 const Cube<eT>&
01361 Cube<eT>::operator%=(const OpCube<T1, op_type>& X)
01362 {
01363 arma_extra_debug_sigprint();
01364
01365 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01366
01367 const Cube<eT> m(X);
01368
01369 return (*this).operator%=(m);
01370 }
01371
01372
01373
01375 template<typename eT>
01376 template<typename T1, typename op_type>
01377 inline
01378 const Cube<eT>&
01379 Cube<eT>::operator/=(const OpCube<T1, op_type>& X)
01380 {
01381 arma_extra_debug_sigprint();
01382
01383 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01384
01385 const Cube<eT> m(X);
01386
01387 return (*this).operator/=(m);
01388 }
01389
01390
01391
01393 template<typename eT>
01394 template<typename T1, typename eop_type>
01395 inline
01396 Cube<eT>::Cube(const eOpCube<T1, eop_type>& X)
01397 : n_rows(X.get_n_rows())
01398 , n_cols(X.get_n_cols())
01399 , n_elem_slice(X.get_n_elem_slice())
01400 , n_slices(X.get_n_slices())
01401 , n_elem(X.get_n_elem())
01402 , mem_state(0)
01403 , mat_ptrs()
01404 , mem()
01405 {
01406 arma_extra_debug_sigprint_this(this);
01407
01408 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01409
01410 init_cold();
01411
01412 eop_type::apply(*this, X);
01413 }
01414
01415
01416
01418 template<typename eT>
01419 template<typename T1, typename eop_type>
01420 inline
01421 const Cube<eT>&
01422 Cube<eT>::operator=(const eOpCube<T1, eop_type>& X)
01423 {
01424 arma_extra_debug_sigprint();
01425
01426 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01427
01428 const bool bad_alias = ( X.P.has_subview && X.P.is_alias(*this) );
01429
01430 if(bad_alias == false)
01431 {
01432 init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
01433
01434 eop_type::apply(*this, X);
01435 }
01436 else
01437 {
01438 Cube<eT> tmp(X);
01439
01440 steal_mem(tmp);
01441 }
01442
01443 return *this;
01444 }
01445
01446
01447
01449 template<typename eT>
01450 template<typename T1, typename eop_type>
01451 inline
01452 const Cube<eT>&
01453 Cube<eT>::operator+=(const eOpCube<T1, eop_type>& X)
01454 {
01455 arma_extra_debug_sigprint();
01456
01457 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01458
01459 eop_type::apply_inplace_plus(*this, X);
01460
01461 return *this;
01462 }
01463
01464
01465
01467 template<typename eT>
01468 template<typename T1, typename eop_type>
01469 inline
01470 const Cube<eT>&
01471 Cube<eT>::operator-=(const eOpCube<T1, eop_type>& X)
01472 {
01473 arma_extra_debug_sigprint();
01474
01475 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01476
01477 eop_type::apply_inplace_minus(*this, X);
01478
01479 return *this;
01480 }
01481
01482
01483
01485 template<typename eT>
01486 template<typename T1, typename eop_type>
01487 inline
01488 const Cube<eT>&
01489 Cube<eT>::operator%=(const eOpCube<T1, eop_type>& X)
01490 {
01491 arma_extra_debug_sigprint();
01492
01493 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01494
01495 eop_type::apply_inplace_schur(*this, X);
01496
01497 return *this;
01498 }
01499
01500
01501
01503 template<typename eT>
01504 template<typename T1, typename eop_type>
01505 inline
01506 const Cube<eT>&
01507 Cube<eT>::operator/=(const eOpCube<T1, eop_type>& X)
01508 {
01509 arma_extra_debug_sigprint();
01510
01511 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01512
01513 eop_type::apply_inplace_div(*this, X);
01514
01515 return *this;
01516 }
01517
01518
01519
01521 template<typename eT>
01522 template<typename T1, typename op_type>
01523 inline
01524 Cube<eT>::Cube(const mtOpCube<eT, T1, op_type>& X)
01525 : n_rows(0)
01526 , n_cols(0)
01527 , n_elem_slice(0)
01528 , n_slices(0)
01529 , n_elem(0)
01530 , mem_state(0)
01531 , mat_ptrs()
01532 , mem()
01533 {
01534 arma_extra_debug_sigprint_this(this);
01535
01536 op_type::apply(*this, X);
01537 }
01538
01539
01540
01542 template<typename eT>
01543 template<typename T1, typename op_type>
01544 inline
01545 const Cube<eT>&
01546 Cube<eT>::operator=(const mtOpCube<eT, T1, op_type>& X)
01547 {
01548 arma_extra_debug_sigprint();
01549
01550 op_type::apply(*this, X);
01551
01552 return *this;
01553 }
01554
01555
01556
01558 template<typename eT>
01559 template<typename T1, typename op_type>
01560 inline
01561 const Cube<eT>&
01562 Cube<eT>::operator+=(const mtOpCube<eT, T1, op_type>& X)
01563 {
01564 arma_extra_debug_sigprint();
01565
01566 const Cube<eT> m(X);
01567
01568 return (*this).operator+=(m);
01569 }
01570
01571
01572
01574 template<typename eT>
01575 template<typename T1, typename op_type>
01576 inline
01577 const Cube<eT>&
01578 Cube<eT>::operator-=(const mtOpCube<eT, T1, op_type>& X)
01579 {
01580 arma_extra_debug_sigprint();
01581
01582 const Cube<eT> m(X);
01583
01584 return (*this).operator-=(m);
01585 }
01586
01587
01588
01590 template<typename eT>
01591 template<typename T1, typename op_type>
01592 inline
01593 const Cube<eT>&
01594 Cube<eT>::operator%=(const mtOpCube<eT, T1, op_type>& X)
01595 {
01596 arma_extra_debug_sigprint();
01597
01598 const Cube<eT> m(X);
01599
01600 return (*this).operator%=(m);
01601 }
01602
01603
01604
01606 template<typename eT>
01607 template<typename T1, typename op_type>
01608 inline
01609 const Cube<eT>&
01610 Cube<eT>::operator/=(const mtOpCube<eT, T1, op_type>& X)
01611 {
01612 arma_extra_debug_sigprint();
01613
01614 const Cube<eT> m(X);
01615
01616 return (*this).operator/=(m);
01617 }
01618
01619
01620
01622 template<typename eT>
01623 template<typename T1, typename T2, typename glue_type>
01624 inline
01625 Cube<eT>::Cube(const GlueCube<T1, T2, glue_type>& X)
01626 : n_rows(0)
01627 , n_cols(0)
01628 , n_elem_slice(0)
01629 , n_slices(0)
01630 , n_elem(0)
01631 , mem_state(0)
01632 , mat_ptrs()
01633 , mem()
01634 {
01635 arma_extra_debug_sigprint_this(this);
01636 this->operator=(X);
01637 }
01638
01639
01640
01642 template<typename eT>
01643 template<typename T1, typename T2, typename glue_type>
01644 inline
01645 const Cube<eT>&
01646 Cube<eT>::operator=(const GlueCube<T1, T2, glue_type>& X)
01647 {
01648 arma_extra_debug_sigprint();
01649
01650 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01651 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01652
01653 glue_type::apply(*this, X);
01654
01655 return *this;
01656 }
01657
01658
01660 template<typename eT>
01661 template<typename T1, typename T2, typename glue_type>
01662 inline
01663 const Cube<eT>&
01664 Cube<eT>::operator+=(const GlueCube<T1, T2, glue_type>& X)
01665 {
01666 arma_extra_debug_sigprint();
01667
01668 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01669 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01670
01671 const Cube<eT> m(X);
01672
01673 return (*this).operator+=(m);
01674 }
01675
01676
01677
01679 template<typename eT>
01680 template<typename T1, typename T2, typename glue_type>
01681 inline
01682 const Cube<eT>&
01683 Cube<eT>::operator-=(const GlueCube<T1, T2, glue_type>& X)
01684 {
01685 arma_extra_debug_sigprint();
01686
01687 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01688 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01689
01690 const Cube<eT> m(X);
01691
01692 return (*this).operator-=(m);
01693 }
01694
01695
01696
01698 template<typename eT>
01699 template<typename T1, typename T2, typename glue_type>
01700 inline
01701 const Cube<eT>&
01702 Cube<eT>::operator%=(const GlueCube<T1, T2, glue_type>& X)
01703 {
01704 arma_extra_debug_sigprint();
01705
01706 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01707 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01708
01709 const Cube<eT> m(X);
01710
01711 return (*this).operator%=(m);
01712 }
01713
01714
01715
01717 template<typename eT>
01718 template<typename T1, typename T2, typename glue_type>
01719 inline
01720 const Cube<eT>&
01721 Cube<eT>::operator/=(const GlueCube<T1, T2, glue_type>& X)
01722 {
01723 arma_extra_debug_sigprint();
01724
01725 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01726 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01727
01728 const Cube<eT> m(X);
01729
01730 return (*this).operator/=(m);
01731 }
01732
01733
01734
01736 template<typename eT>
01737 template<typename T1, typename T2, typename eglue_type>
01738 inline
01739 Cube<eT>::Cube(const eGlueCube<T1, T2, eglue_type>& X)
01740 : n_rows(X.get_n_rows())
01741 , n_cols(X.get_n_cols())
01742 , n_elem_slice(X.get_n_elem_slice())
01743 , n_slices(X.get_n_slices())
01744 , n_elem(X.get_n_elem())
01745 , mem_state(0)
01746 , mat_ptrs()
01747 , mem()
01748 {
01749 arma_extra_debug_sigprint_this(this);
01750
01751 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01752 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01753
01754 init_cold();
01755
01756 eglue_type::apply(*this, X);
01757 }
01758
01759
01760
01762 template<typename eT>
01763 template<typename T1, typename T2, typename eglue_type>
01764 inline
01765 const Cube<eT>&
01766 Cube<eT>::operator=(const eGlueCube<T1, T2, eglue_type>& X)
01767 {
01768 arma_extra_debug_sigprint();
01769
01770 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01771 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01772
01773 const bool bad_alias = ( (X.P1.has_subview && X.P1.is_alias(*this)) || (X.P2.has_subview && X.P2.is_alias(*this)) );
01774
01775 if(bad_alias == false)
01776 {
01777 init_warm(X.get_n_rows(), X.get_n_cols(), X.get_n_slices());
01778
01779 eglue_type::apply(*this, X);
01780 }
01781 else
01782 {
01783 Cube<eT> tmp(X);
01784
01785 steal_mem(tmp);
01786 }
01787
01788 return *this;
01789 }
01790
01791
01792
01794 template<typename eT>
01795 template<typename T1, typename T2, typename eglue_type>
01796 inline
01797 const Cube<eT>&
01798 Cube<eT>::operator+=(const eGlueCube<T1, T2, eglue_type>& X)
01799 {
01800 arma_extra_debug_sigprint();
01801
01802 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01803 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01804
01805 eglue_type::apply_inplace_plus(*this, X);
01806
01807 return *this;
01808 }
01809
01810
01811
01813 template<typename eT>
01814 template<typename T1, typename T2, typename eglue_type>
01815 inline
01816 const Cube<eT>&
01817 Cube<eT>::operator-=(const eGlueCube<T1, T2, eglue_type>& X)
01818 {
01819 arma_extra_debug_sigprint();
01820
01821 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01822 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01823
01824 eglue_type::apply_inplace_minus(*this, X);
01825
01826 return *this;
01827 }
01828
01829
01830
01832 template<typename eT>
01833 template<typename T1, typename T2, typename eglue_type>
01834 inline
01835 const Cube<eT>&
01836 Cube<eT>::operator%=(const eGlueCube<T1, T2, eglue_type>& X)
01837 {
01838 arma_extra_debug_sigprint();
01839
01840 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01841 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01842
01843 eglue_type::apply_inplace_schur(*this, X);
01844
01845 return *this;
01846 }
01847
01848
01849
01851 template<typename eT>
01852 template<typename T1, typename T2, typename eglue_type>
01853 inline
01854 const Cube<eT>&
01855 Cube<eT>::operator/=(const eGlueCube<T1, T2, eglue_type>& X)
01856 {
01857 arma_extra_debug_sigprint();
01858
01859 arma_type_check(( is_same_type< eT, typename T1::elem_type >::value == false ));
01860 arma_type_check(( is_same_type< eT, typename T2::elem_type >::value == false ));
01861
01862 eglue_type::apply_inplace_div(*this, X);
01863
01864 return *this;
01865 }
01866
01867
01868
01870 template<typename eT>
01871 template<typename T1, typename T2, typename glue_type>
01872 inline
01873 Cube<eT>::Cube(const mtGlueCube<eT, T1, T2, glue_type>& X)
01874 : n_rows(0)
01875 , n_cols(0)
01876 , n_elem_slice(0)
01877 , n_slices(0)
01878 , n_elem(0)
01879 , mem_state(0)
01880 , mat_ptrs()
01881 , mem()
01882 {
01883 arma_extra_debug_sigprint_this(this);
01884
01885 glue_type::apply(*this, X);
01886 }
01887
01888
01889
01891 template<typename eT>
01892 template<typename T1, typename T2, typename glue_type>
01893 inline
01894 const Cube<eT>&
01895 Cube<eT>::operator=(const mtGlueCube<eT, T1, T2, glue_type>& X)
01896 {
01897 arma_extra_debug_sigprint();
01898
01899 glue_type::apply(*this, X);
01900
01901 return *this;
01902 }
01903
01904
01905
01907 template<typename eT>
01908 template<typename T1, typename T2, typename glue_type>
01909 inline
01910 const Cube<eT>&
01911 Cube<eT>::operator+=(const mtGlueCube<eT, T1, T2, glue_type>& X)
01912 {
01913 arma_extra_debug_sigprint();
01914
01915 const Cube<eT> m(X);
01916
01917 return (*this).operator+=(m);
01918 }
01919
01920
01921
01923 template<typename eT>
01924 template<typename T1, typename T2, typename glue_type>
01925 inline
01926 const Cube<eT>&
01927 Cube<eT>::operator-=(const mtGlueCube<eT, T1, T2, glue_type>& X)
01928 {
01929 arma_extra_debug_sigprint();
01930
01931 const Cube<eT> m(X);
01932
01933 return (*this).operator-=(m);
01934 }
01935
01936
01937
01939 template<typename eT>
01940 template<typename T1, typename T2, typename glue_type>
01941 inline
01942 const Cube<eT>&
01943 Cube<eT>::operator%=(const mtGlueCube<eT, T1, T2, glue_type>& X)
01944 {
01945 arma_extra_debug_sigprint();
01946
01947 const Cube<eT> m(X);
01948
01949 return (*this).operator%=(m);
01950 }
01951
01952
01953
01955 template<typename eT>
01956 template<typename T1, typename T2, typename glue_type>
01957 inline
01958 const Cube<eT>&
01959 Cube<eT>::operator/=(const mtGlueCube<eT, T1, T2, glue_type>& X)
01960 {
01961 arma_extra_debug_sigprint();
01962
01963 const Cube<eT> m(X);
01964
01965 return (*this).operator/=(m);
01966 }
01967
01968
01969
01971 template<typename eT>
01972 arma_inline
01973 arma_warn_unused
01974 eT&
01975 Cube<eT>::operator() (const uword i)
01976 {
01977 arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
01978 return access::rw(mem[i]);
01979 }
01980
01981
01982
01984 template<typename eT>
01985 arma_inline
01986 arma_warn_unused
01987 eT
01988 Cube<eT>::operator() (const uword i) const
01989 {
01990 arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
01991 return mem[i];
01992 }
01993
01994
01996 template<typename eT>
01997 arma_inline
01998 arma_warn_unused
01999 eT&
02000 Cube<eT>::operator[] (const uword i)
02001 {
02002 return access::rw(mem[i]);
02003 }
02004
02005
02006
02008 template<typename eT>
02009 arma_inline
02010 arma_warn_unused
02011 eT
02012 Cube<eT>::operator[] (const uword i) const
02013 {
02014 return mem[i];
02015 }
02016
02017
02018
02020 template<typename eT>
02021 arma_inline
02022 arma_warn_unused
02023 eT&
02024 Cube<eT>::at(const uword i)
02025 {
02026 return access::rw(mem[i]);
02027 }
02028
02029
02030
02032 template<typename eT>
02033 arma_inline
02034 arma_warn_unused
02035 eT
02036 Cube<eT>::at(const uword i) const
02037 {
02038 return mem[i];
02039 }
02040
02041
02042
02044 template<typename eT>
02045 arma_inline
02046 arma_warn_unused
02047 eT&
02048 Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice)
02049 {
02050 arma_debug_check
02051 (
02052 (in_row >= n_rows) ||
02053 (in_col >= n_cols) ||
02054 (in_slice >= n_slices)
02055 ,
02056 "Cube::operator(): index out of bounds"
02057 );
02058
02059 return access::rw(mem[in_slice*n_elem_slice + in_col*n_rows + in_row]);
02060 }
02061
02062
02063
02065 template<typename eT>
02066 arma_inline
02067 arma_warn_unused
02068 eT
02069 Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_slice) const
02070 {
02071 arma_debug_check
02072 (
02073 (in_row >= n_rows) ||
02074 (in_col >= n_cols) ||
02075 (in_slice >= n_slices)
02076 ,
02077 "Cube::operator(): index out of bounds"
02078 );
02079
02080 return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
02081 }
02082
02083
02084
02086 template<typename eT>
02087 arma_inline
02088 arma_warn_unused
02089 eT&
02090 Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice)
02091 {
02092 return access::rw( mem[in_slice*n_elem_slice + in_col*n_rows + in_row] );
02093 }
02094
02095
02096
02098 template<typename eT>
02099 arma_inline
02100 arma_warn_unused
02101 eT
02102 Cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) const
02103 {
02104 return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
02105 }
02106
02107
02108
02110 template<typename eT>
02111 arma_inline
02112 const Cube<eT>&
02113 Cube<eT>::operator++()
02114 {
02115 Cube_aux::prefix_pp(*this);
02116 return *this;
02117 }
02118
02119
02120
02122 template<typename eT>
02123 arma_inline
02124 void
02125 Cube<eT>::operator++(int)
02126 {
02127 Cube_aux::postfix_pp(*this);
02128 }
02129
02130
02131
02133 template<typename eT>
02134 arma_inline
02135 const Cube<eT>&
02136 Cube<eT>::operator--()
02137 {
02138 Cube_aux::prefix_mm(*this);
02139 return *this;
02140 }
02141
02142
02143
02145 template<typename eT>
02146 arma_inline
02147 void
02148 Cube<eT>::operator--(int)
02149 {
02150 Cube_aux::postfix_mm(*this);
02151 }
02152
02153
02154
02156 template<typename eT>
02157 arma_inline
02158 arma_warn_unused
02159 bool
02160 Cube<eT>::is_finite() const
02161 {
02162 return arrayops::is_finite( memptr(), n_elem );
02163 }
02164
02165
02166
02168 template<typename eT>
02169 arma_inline
02170 arma_warn_unused
02171 bool
02172 Cube<eT>::is_empty() const
02173 {
02174 return (n_elem == 0);
02175 }
02176
02177
02178
02180 template<typename eT>
02181 arma_inline
02182 arma_warn_unused
02183 bool
02184 Cube<eT>::in_range(const uword i) const
02185 {
02186 return (i < n_elem);
02187 }
02188
02189
02190
02192 template<typename eT>
02193 arma_inline
02194 arma_warn_unused
02195 bool
02196 Cube<eT>::in_range(const span& x) const
02197 {
02198 arma_extra_debug_sigprint();
02199
02200 if(x.whole == true)
02201 {
02202 return true;
02203 }
02204 else
02205 {
02206 const uword a = x.a;
02207 const uword b = x.b;
02208
02209 return ( (a <= b) && (b < n_elem) );
02210 }
02211 }
02212
02213
02214
02216 template<typename eT>
02217 arma_inline
02218 arma_warn_unused
02219 bool
02220 Cube<eT>::in_range(const uword in_row, const uword in_col, const uword in_slice) const
02221 {
02222 return ( (in_row < n_rows) && (in_col < n_cols) && (in_slice < n_slices) );
02223 }
02224
02225
02226
02227 template<typename eT>
02228 inline
02229 arma_warn_unused
02230 bool
02231 Cube<eT>::in_range(const span& row_span, const span& col_span, const span& slice_span) const
02232 {
02233 arma_extra_debug_sigprint();
02234
02235 const uword in_row1 = row_span.a;
02236 const uword in_row2 = row_span.b;
02237
02238 const uword in_col1 = col_span.a;
02239 const uword in_col2 = col_span.b;
02240
02241 const uword in_slice1 = slice_span.a;
02242 const uword in_slice2 = slice_span.b;
02243
02244
02245 const bool rows_ok = row_span.whole ? true : ( (in_row1 <= in_row2) && (in_row2 < n_rows) );
02246 const bool cols_ok = col_span.whole ? true : ( (in_col1 <= in_col2) && (in_col2 < n_cols) );
02247 const bool slices_ok = slice_span.whole ? true : ( (in_slice1 <= in_slice2) && (in_slice2 < n_slices) );
02248
02249
02250 return ( (rows_ok == true) && (cols_ok == true) && (slices_ok == true) );
02251 }
02252
02253
02254
02256 template<typename eT>
02257 arma_inline
02258 arma_warn_unused
02259 eT*
02260 Cube<eT>::memptr()
02261 {
02262 return const_cast<eT*>(mem);
02263 }
02264
02265
02266
02268 template<typename eT>
02269 arma_inline
02270 arma_warn_unused
02271 const eT*
02272 Cube<eT>::memptr() const
02273 {
02274 return mem;
02275 }
02276
02277
02278
02280 template<typename eT>
02281 arma_inline
02282 arma_warn_unused
02283 eT*
02284 Cube<eT>::slice_memptr(const uword slice)
02285 {
02286 return const_cast<eT*>( &mem[ slice*n_elem_slice ] );
02287 }
02288
02289
02290
02292 template<typename eT>
02293 arma_inline
02294 arma_warn_unused
02295 const eT*
02296 Cube<eT>::slice_memptr(const uword slice) const
02297 {
02298 return &mem[ slice*n_elem_slice ];
02299 }
02300
02301
02302
02304 template<typename eT>
02305 arma_inline
02306 arma_warn_unused
02307 eT*
02308 Cube<eT>::slice_colptr(const uword slice, const uword col)
02309 {
02310 return const_cast<eT*>( &mem[ slice*n_elem_slice + col*n_rows] );
02311 }
02312
02313
02314
02316 template<typename eT>
02317 arma_inline
02318 arma_warn_unused
02319 const eT*
02320 Cube<eT>::slice_colptr(const uword slice, const uword col) const
02321 {
02322 return &mem[ slice*n_elem_slice + col*n_rows ];
02323 }
02324
02325
02326
02331 template<typename eT>
02332 inline
02333 void
02334 Cube<eT>::impl_print(const std::string& extra_text) const
02335 {
02336 arma_extra_debug_sigprint();
02337
02338 if(extra_text.length() != 0)
02339 {
02340 cout << extra_text << '\n';
02341 }
02342
02343 arma_ostream::print(cout, *this, true);
02344 }
02345
02346
02351 template<typename eT>
02352 inline
02353 void
02354 Cube<eT>::impl_print(std::ostream& user_stream, const std::string& extra_text) const
02355 {
02356 arma_extra_debug_sigprint();
02357
02358 if(extra_text.length() != 0)
02359 {
02360 user_stream << extra_text << '\n';
02361 }
02362
02363 arma_ostream::print(user_stream, *this, true);
02364 }
02365
02366
02367
02372 template<typename eT>
02373 inline
02374 void
02375 Cube<eT>::impl_raw_print(const std::string& extra_text) const
02376 {
02377 arma_extra_debug_sigprint();
02378
02379 if(extra_text.length() != 0)
02380 {
02381 cout << extra_text << '\n';
02382 }
02383
02384 arma_ostream::print(cout, *this, false);
02385 }
02386
02387
02388
02393 template<typename eT>
02394 inline
02395 void
02396 Cube<eT>::impl_raw_print(std::ostream& user_stream, const std::string& extra_text) const
02397 {
02398 arma_extra_debug_sigprint();
02399
02400 if(extra_text.length() != 0)
02401 {
02402 user_stream << extra_text << '\n';
02403 }
02404
02405 arma_ostream::print(user_stream, *this, false);
02406 }
02407
02408
02409
02411 template<typename eT>
02412 inline
02413 void
02414 Cube<eT>::set_size(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices)
02415 {
02416 arma_extra_debug_sigprint();
02417
02418 init_warm(in_n_rows, in_n_cols, in_n_slices);
02419 }
02420
02421
02422
02424 template<typename eT>
02425 inline
02426 void
02427 Cube<eT>::reshape(const uword in_rows, const uword in_cols, const uword in_slices, const uword dim)
02428 {
02429 arma_extra_debug_sigprint();
02430
02431 *this = arma::reshape(*this, in_rows, in_cols, in_slices, dim);
02432 }
02433
02434
02435
02437 template<typename eT>
02438 inline
02439 void
02440 Cube<eT>::resize(const uword in_rows, const uword in_cols, const uword in_slices)
02441 {
02442 arma_extra_debug_sigprint();
02443
02444 *this = arma::resize(*this, in_rows, in_cols, in_slices);
02445 }
02446
02447
02448
02450 template<typename eT>
02451 template<typename eT2>
02452 inline
02453 void
02454 Cube<eT>::copy_size(const Cube<eT2>& m)
02455 {
02456 arma_extra_debug_sigprint();
02457
02458 init_warm(m.n_rows, m.n_cols, m.n_slices);
02459 }
02460
02461
02462
02464 template<typename eT>
02465 inline
02466 const Cube<eT>&
02467 Cube<eT>::fill(const eT val)
02468 {
02469 arma_extra_debug_sigprint();
02470
02471 arrayops::inplace_set( memptr(), val, n_elem );
02472
02473 return *this;
02474 }
02475
02476
02477
02478 template<typename eT>
02479 inline
02480 const Cube<eT>&
02481 Cube<eT>::zeros()
02482 {
02483 arma_extra_debug_sigprint();
02484
02485 return (*this).fill(eT(0));
02486 }
02487
02488
02489
02490 template<typename eT>
02491 inline
02492 const Cube<eT>&
02493 Cube<eT>::zeros(const uword in_rows, const uword in_cols, const uword in_slices)
02494 {
02495 arma_extra_debug_sigprint();
02496
02497 set_size(in_rows, in_cols, in_slices);
02498
02499 return (*this).fill(eT(0));
02500 }
02501
02502
02503
02504 template<typename eT>
02505 inline
02506 const Cube<eT>&
02507 Cube<eT>::ones()
02508 {
02509 arma_extra_debug_sigprint();
02510
02511 return (*this).fill(eT(1));
02512 }
02513
02514
02515
02516 template<typename eT>
02517 inline
02518 const Cube<eT>&
02519 Cube<eT>::ones(const uword in_rows, const uword in_cols, const uword in_slices)
02520 {
02521 arma_extra_debug_sigprint();
02522
02523 set_size(in_rows, in_cols, in_slices);
02524
02525 return (*this).fill(eT(1));
02526 }
02527
02528
02529
02530 template<typename eT>
02531 inline
02532 const Cube<eT>&
02533 Cube<eT>::randu()
02534 {
02535 arma_extra_debug_sigprint();
02536
02537 const uword N = n_elem;
02538 eT* ptr = memptr();
02539
02540 uword i,j;
02541
02542 for(i=0, j=1; j<N; i+=2, j+=2)
02543 {
02544 ptr[i] = eT(eop_aux_randu<eT>());
02545 ptr[j] = eT(eop_aux_randu<eT>());
02546 }
02547
02548 if(i < N)
02549 {
02550 ptr[i] = eT(eop_aux_randu<eT>());
02551 }
02552
02553 return *this;
02554 }
02555
02556
02557
02558 template<typename eT>
02559 inline
02560 const Cube<eT>&
02561 Cube<eT>::randu(const uword in_rows, const uword in_cols, const uword in_slices)
02562 {
02563 arma_extra_debug_sigprint();
02564
02565 set_size(in_rows, in_cols, in_slices);
02566
02567 return (*this).randu();
02568 }
02569
02570
02571
02572 template<typename eT>
02573 inline
02574 const Cube<eT>&
02575 Cube<eT>::randn()
02576 {
02577 arma_extra_debug_sigprint();
02578
02579 const uword N = n_elem;
02580 eT* ptr = memptr();
02581
02582 for(uword i=0; i<N; ++i)
02583 {
02584 ptr[i] = eT(eop_aux_randn<eT>());
02585 }
02586
02587 return *this;
02588 }
02589
02590
02591
02592 template<typename eT>
02593 inline
02594 const Cube<eT>&
02595 Cube<eT>::randn(const uword in_rows, const uword in_cols, const uword in_slices)
02596 {
02597 arma_extra_debug_sigprint();
02598
02599 set_size(in_rows, in_cols, in_slices);
02600
02601 return (*this).randn();
02602 }
02603
02604
02605
02606 template<typename eT>
02607 inline
02608 void
02609 Cube<eT>::reset()
02610 {
02611 arma_extra_debug_sigprint();
02612
02613 init_warm(0,0,0);
02614 }
02615
02616
02617
02618 template<typename eT>
02619 template<typename T1>
02620 inline
02621 void
02622 Cube<eT>::set_real(const BaseCube<typename Cube<eT>::pod_type,T1>& X)
02623 {
02624 arma_extra_debug_sigprint();
02625
02626 Cube_aux::set_real(*this, X);
02627 }
02628
02629
02630
02631 template<typename eT>
02632 template<typename T1>
02633 inline
02634 void
02635 Cube<eT>::set_imag(const BaseCube<typename Cube<eT>::pod_type,T1>& X)
02636 {
02637 arma_extra_debug_sigprint();
02638
02639 Cube_aux::set_imag(*this, X);
02640 }
02641
02642
02643
02644 template<typename eT>
02645 inline
02646 arma_warn_unused
02647 eT
02648 Cube<eT>::min() const
02649 {
02650 arma_extra_debug_sigprint();
02651
02652 arma_debug_check( (n_elem == 0), "min(): object has no elements" );
02653
02654 return op_min::direct_min(memptr(), n_elem);
02655 }
02656
02657
02658
02659 template<typename eT>
02660 inline
02661 arma_warn_unused
02662 eT
02663 Cube<eT>::max() const
02664 {
02665 arma_extra_debug_sigprint();
02666
02667 arma_debug_check( (n_elem == 0), "max(): object has no elements" );
02668
02669 return op_max::direct_max(memptr(), n_elem);
02670 }
02671
02672
02673
02674 template<typename eT>
02675 inline
02676 eT
02677 Cube<eT>::min(uword& index_of_min_val) const
02678 {
02679 arma_extra_debug_sigprint();
02680
02681 arma_debug_check( (n_elem == 0), "min(): object has no elements" );
02682
02683 return op_min::direct_min(memptr(), n_elem, index_of_min_val);
02684 }
02685
02686
02687
02688 template<typename eT>
02689 inline
02690 eT
02691 Cube<eT>::max(uword& index_of_max_val) const
02692 {
02693 arma_extra_debug_sigprint();
02694
02695 arma_debug_check( (n_elem == 0), "max(): object has no elements" );
02696
02697 return op_max::direct_max(memptr(), n_elem, index_of_max_val);
02698 }
02699
02700
02701
02702 template<typename eT>
02703 inline
02704 eT
02705 Cube<eT>::min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const
02706 {
02707 arma_extra_debug_sigprint();
02708
02709 arma_debug_check( (n_elem == 0), "min(): object has no elements" );
02710
02711 uword i;
02712
02713 eT val = op_min::direct_min(memptr(), n_elem, i);
02714
02715 const uword in_slice = i / n_elem_slice;
02716 const uword offset = in_slice * n_elem_slice;
02717 const uword j = i - offset;
02718
02719 row_of_min_val = j % n_rows;
02720 col_of_min_val = j / n_rows;
02721 slice_of_min_val = in_slice;
02722
02723 return val;
02724 }
02725
02726
02727
02728 template<typename eT>
02729 inline
02730 eT
02731 Cube<eT>::max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const
02732 {
02733 arma_extra_debug_sigprint();
02734
02735 arma_debug_check( (n_elem == 0), "max(): object has no elements" );
02736
02737 uword i;
02738
02739 eT val = op_max::direct_max(memptr(), n_elem, i);
02740
02741 const uword in_slice = i / n_elem_slice;
02742 const uword offset = in_slice * n_elem_slice;
02743 const uword j = i - offset;
02744
02745 row_of_max_val = j % n_rows;
02746 col_of_max_val = j / n_rows;
02747 slice_of_max_val = in_slice;
02748
02749 return val;
02750 }
02751
02752
02753
02755 template<typename eT>
02756 inline
02757 bool
02758 Cube<eT>::save(const std::string name, const file_type type, const bool print_status) const
02759 {
02760 arma_extra_debug_sigprint();
02761
02762 bool save_okay;
02763
02764 switch(type)
02765 {
02766 case raw_ascii:
02767 save_okay = diskio::save_raw_ascii(*this, name);
02768 break;
02769
02770 case arma_ascii:
02771 save_okay = diskio::save_arma_ascii(*this, name);
02772 break;
02773
02774 case raw_binary:
02775 save_okay = diskio::save_raw_binary(*this, name);
02776 break;
02777
02778 case arma_binary:
02779 save_okay = diskio::save_arma_binary(*this, name);
02780 break;
02781
02782 case ppm_binary:
02783 save_okay = diskio::save_ppm_binary(*this, name);
02784 break;
02785
02786 default:
02787 arma_warn(print_status, "Cube::save(): unsupported file type");
02788 save_okay = false;
02789 }
02790
02791 arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to ", name);
02792
02793 return save_okay;
02794 }
02795
02796
02797
02799 template<typename eT>
02800 inline
02801 bool
02802 Cube<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
02803 {
02804 arma_extra_debug_sigprint();
02805
02806 bool save_okay;
02807
02808 switch(type)
02809 {
02810 case raw_ascii:
02811 save_okay = diskio::save_raw_ascii(*this, os);
02812 break;
02813
02814 case arma_ascii:
02815 save_okay = diskio::save_arma_ascii(*this, os);
02816 break;
02817
02818 case raw_binary:
02819 save_okay = diskio::save_raw_binary(*this, os);
02820 break;
02821
02822 case arma_binary:
02823 save_okay = diskio::save_arma_binary(*this, os);
02824 break;
02825
02826 case ppm_binary:
02827 save_okay = diskio::save_ppm_binary(*this, os);
02828 break;
02829
02830 default:
02831 arma_warn(print_status, "Cube::save(): unsupported file type");
02832 save_okay = false;
02833 }
02834
02835 arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to given stream");
02836
02837 return save_okay;
02838 }
02839
02840
02841
02843 template<typename eT>
02844 inline
02845 bool
02846 Cube<eT>::load(const std::string name, const file_type type, const bool print_status)
02847 {
02848 arma_extra_debug_sigprint();
02849
02850 bool load_okay;
02851 std::string err_msg;
02852
02853 switch(type)
02854 {
02855 case auto_detect:
02856 load_okay = diskio::load_auto_detect(*this, name, err_msg);
02857 break;
02858
02859 case raw_ascii:
02860 load_okay = diskio::load_raw_ascii(*this, name, err_msg);
02861 break;
02862
02863 case arma_ascii:
02864 load_okay = diskio::load_arma_ascii(*this, name, err_msg);
02865 break;
02866
02867 case raw_binary:
02868 load_okay = diskio::load_raw_binary(*this, name, err_msg);
02869 break;
02870
02871 case arma_binary:
02872 load_okay = diskio::load_arma_binary(*this, name, err_msg);
02873 break;
02874
02875 case ppm_binary:
02876 load_okay = diskio::load_ppm_binary(*this, name, err_msg);
02877 break;
02878
02879 default:
02880 arma_warn(print_status, "Cube::load(): unsupported file type");
02881 load_okay = false;
02882 }
02883
02884 if( (print_status == true) && (load_okay == false) )
02885 {
02886 if(err_msg.length() > 0)
02887 {
02888 arma_warn(true, "Cube::load(): ", err_msg, name);
02889 }
02890 else
02891 {
02892 arma_warn(true, "Cube::load(): couldn't read ", name);
02893 }
02894 }
02895
02896 if(load_okay == false)
02897 {
02898 (*this).reset();
02899 }
02900
02901 return load_okay;
02902 }
02903
02904
02905
02907 template<typename eT>
02908 inline
02909 bool
02910 Cube<eT>::load(std::istream& is, const file_type type, const bool print_status)
02911 {
02912 arma_extra_debug_sigprint();
02913
02914 bool load_okay;
02915 std::string err_msg;
02916
02917 switch(type)
02918 {
02919 case auto_detect:
02920 load_okay = diskio::load_auto_detect(*this, is, err_msg);
02921 break;
02922
02923 case raw_ascii:
02924 load_okay = diskio::load_raw_ascii(*this, is, err_msg);
02925 break;
02926
02927 case arma_ascii:
02928 load_okay = diskio::load_arma_ascii(*this, is, err_msg);
02929 break;
02930
02931 case raw_binary:
02932 load_okay = diskio::load_raw_binary(*this, is, err_msg);
02933 break;
02934
02935 case arma_binary:
02936 load_okay = diskio::load_arma_binary(*this, is, err_msg);
02937 break;
02938
02939 case ppm_binary:
02940 load_okay = diskio::load_ppm_binary(*this, is, err_msg);
02941 break;
02942
02943 default:
02944 arma_warn(print_status, "Cube::load(): unsupported file type");
02945 load_okay = false;
02946 }
02947
02948
02949 if( (print_status == true) && (load_okay == false) )
02950 {
02951 if(err_msg.length() > 0)
02952 {
02953 arma_warn(true, "Cube::load(): ", err_msg, "the given stream");
02954 }
02955 else
02956 {
02957 arma_warn(true, "Cube::load(): couldn't load from the given stream");
02958 }
02959 }
02960
02961 if(load_okay == false)
02962 {
02963 (*this).reset();
02964 }
02965
02966 return load_okay;
02967 }
02968
02969
02970
02972 template<typename eT>
02973 inline
02974 bool
02975 Cube<eT>::quiet_save(const std::string name, const file_type type) const
02976 {
02977 arma_extra_debug_sigprint();
02978
02979 return (*this).save(name, type, false);
02980 }
02981
02982
02983
02985 template<typename eT>
02986 inline
02987 bool
02988 Cube<eT>::quiet_save(std::ostream& os, const file_type type) const
02989 {
02990 arma_extra_debug_sigprint();
02991
02992 return (*this).save(os, type, false);
02993 }
02994
02995
02996
02998 template<typename eT>
02999 inline
03000 bool
03001 Cube<eT>::quiet_load(const std::string name, const file_type type)
03002 {
03003 arma_extra_debug_sigprint();
03004
03005 return (*this).load(name, type, false);
03006 }
03007
03008
03009
03011 template<typename eT>
03012 inline
03013 bool
03014 Cube<eT>::quiet_load(std::istream& is, const file_type type)
03015 {
03016 arma_extra_debug_sigprint();
03017
03018 return (*this).load(is, type, false);
03019 }
03020
03021
03022
03023 template<typename eT>
03024 inline
03025 typename Cube<eT>::iterator
03026 Cube<eT>::begin()
03027 {
03028 arma_extra_debug_sigprint();
03029
03030 return memptr();
03031 }
03032
03033
03034
03035 template<typename eT>
03036 inline
03037 typename Cube<eT>::const_iterator
03038 Cube<eT>::begin() const
03039 {
03040 arma_extra_debug_sigprint();
03041
03042 return memptr();
03043 }
03044
03045
03046
03047 template<typename eT>
03048 inline
03049 typename Cube<eT>::iterator
03050 Cube<eT>::end()
03051 {
03052 arma_extra_debug_sigprint();
03053
03054 return memptr() + n_elem;
03055 }
03056
03057
03058
03059 template<typename eT>
03060 inline
03061 typename Cube<eT>::const_iterator
03062 Cube<eT>::end() const
03063 {
03064 arma_extra_debug_sigprint();
03065
03066 return memptr() + n_elem;
03067 }
03068
03069
03070
03071 template<typename eT>
03072 inline
03073 typename Cube<eT>::slice_iterator
03074 Cube<eT>::begin_slice(const uword slice_num)
03075 {
03076 arma_extra_debug_sigprint();
03077
03078 arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
03079
03080 return slice_memptr(slice_num);
03081 }
03082
03083
03084
03085 template<typename eT>
03086 inline
03087 typename Cube<eT>::const_slice_iterator
03088 Cube<eT>::begin_slice(const uword slice_num) const
03089 {
03090 arma_extra_debug_sigprint();
03091
03092 arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
03093
03094 return slice_memptr(slice_num);
03095 }
03096
03097
03098
03099 template<typename eT>
03100 inline
03101 typename Cube<eT>::slice_iterator
03102 Cube<eT>::end_slice(const uword slice_num)
03103 {
03104 arma_extra_debug_sigprint();
03105
03106 arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
03107
03108 return slice_memptr(slice_num) + n_elem_slice;
03109 }
03110
03111
03112
03113 template<typename eT>
03114 inline
03115 typename Cube<eT>::const_slice_iterator
03116 Cube<eT>::end_slice(const uword slice_num) const
03117 {
03118 arma_extra_debug_sigprint();
03119
03120 arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
03121
03122 return slice_memptr(slice_num) + n_elem_slice;
03123 }
03124
03125
03126
03127 template<typename eT>
03128 template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
03129 arma_inline
03130 void
03131 Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::mem_setup()
03132 {
03133 arma_extra_debug_sigprint_this(this);
03134
03135 if(fixed_n_elem > 0)
03136 {
03137 access::rw(Cube<eT>::n_rows) = fixed_n_rows;
03138 access::rw(Cube<eT>::n_cols) = fixed_n_cols;
03139 access::rw(Cube<eT>::n_elem_slice) = fixed_n_rows * fixed_n_cols;
03140 access::rw(Cube<eT>::n_slices) = fixed_n_slices;
03141 access::rw(Cube<eT>::n_elem) = fixed_n_elem;
03142 access::rw(Cube<eT>::mem_state) = 3;
03143 access::rw(Cube<eT>::mat_ptrs) = const_cast< const Mat<eT>** >( \
03144 (fixed_n_slices > Cube_prealloc::mat_ptrs_size) ? mat_ptrs_local_extra : mat_ptrs_local );
03145 access::rw(Cube<eT>::mem) = (fixed_n_elem > Cube_prealloc::mem_n_elem) ? mem_local_extra : mem_local;
03146
03147 create_mat();
03148 }
03149 else
03150 {
03151 access::rw(Cube<eT>::n_rows) = 0;
03152 access::rw(Cube<eT>::n_cols) = 0;
03153 access::rw(Cube<eT>::n_elem_slice) = 0;
03154 access::rw(Cube<eT>::n_slices) = 0;
03155 access::rw(Cube<eT>::n_elem) = 0;
03156 access::rw(Cube<eT>::mem_state) = 3;
03157 access::rw(Cube<eT>::mat_ptrs) = 0;
03158 access::rw(Cube<eT>::mem) = 0;
03159 }
03160 }
03161
03162
03163
03165 template<typename eT>
03166 arma_inline
03167 void
03168 Cube_aux::prefix_pp(Cube<eT>& x)
03169 {
03170 eT* memptr = x.memptr();
03171 const uword n_elem = x.n_elem;
03172
03173 uword i,j;
03174
03175 for(i=0, j=1; j<n_elem; i+=2, j+=2)
03176 {
03177 ++(memptr[i]);
03178 ++(memptr[j]);
03179 }
03180
03181 if(i < n_elem)
03182 {
03183 ++(memptr[i]);
03184 }
03185 }
03186
03187
03188
03190 template<typename T>
03191 arma_inline
03192 void
03193 Cube_aux::prefix_pp(Cube< std::complex<T> >& x)
03194 {
03195 x += T(1);
03196 }
03197
03198
03199
03201 template<typename eT>
03202 arma_inline
03203 void
03204 Cube_aux::postfix_pp(Cube<eT>& x)
03205 {
03206 eT* memptr = x.memptr();
03207 const uword n_elem = x.n_elem;
03208
03209 uword i,j;
03210
03211 for(i=0, j=1; j<n_elem; i+=2, j+=2)
03212 {
03213 (memptr[i])++;
03214 (memptr[j])++;
03215 }
03216
03217 if(i < n_elem)
03218 {
03219 (memptr[i])++;
03220 }
03221 }
03222
03223
03224
03226 template<typename T>
03227 arma_inline
03228 void
03229 Cube_aux::postfix_pp(Cube< std::complex<T> >& x)
03230 {
03231 x += T(1);
03232 }
03233
03234
03235
03237 template<typename eT>
03238 arma_inline
03239 void
03240 Cube_aux::prefix_mm(Cube<eT>& x)
03241 {
03242 eT* memptr = x.memptr();
03243 const uword n_elem = x.n_elem;
03244
03245 uword i,j;
03246
03247 for(i=0, j=1; j<n_elem; i+=2, j+=2)
03248 {
03249 --(memptr[i]);
03250 --(memptr[j]);
03251 }
03252
03253 if(i < n_elem)
03254 {
03255 --(memptr[i]);
03256 }
03257 }
03258
03259
03260
03262 template<typename T>
03263 arma_inline
03264 void
03265 Cube_aux::prefix_mm(Cube< std::complex<T> >& x)
03266 {
03267 x -= T(1);
03268 }
03269
03270
03271
03273 template<typename eT>
03274 arma_inline
03275 void
03276 Cube_aux::postfix_mm(Cube<eT>& x)
03277 {
03278 eT* memptr = x.memptr();
03279 const uword n_elem = x.n_elem;
03280
03281 uword i,j;
03282
03283 for(i=0, j=1; j<n_elem; i+=2, j+=2)
03284 {
03285 (memptr[i])--;
03286 (memptr[j])--;
03287 }
03288
03289 if(i < n_elem)
03290 {
03291 (memptr[i])--;
03292 }
03293 }
03294
03295
03296
03298 template<typename T>
03299 arma_inline
03300 void
03301 Cube_aux::postfix_mm(Cube< std::complex<T> >& x)
03302 {
03303 x -= T(1);
03304 }
03305
03306
03307
03308 template<typename eT, typename T1>
03309 inline
03310 void
03311 Cube_aux::set_real(Cube<eT>& out, const BaseCube<eT,T1>& X)
03312 {
03313 arma_extra_debug_sigprint();
03314
03315 const unwrap_cube<T1> tmp(X.get_ref());
03316 const Cube<eT>& A = tmp.M;
03317
03318 arma_debug_assert_same_size( out, A, "Cube::set_real()" );
03319
03320 out = A;
03321 }
03322
03323
03324
03325 template<typename eT, typename T1>
03326 inline
03327 void
03328 Cube_aux::set_imag(Cube<eT>& out, const BaseCube<eT,T1>& X)
03329 {
03330 arma_extra_debug_sigprint();
03331 }
03332
03333
03334
03335 template<typename T, typename T1>
03336 inline
03337 void
03338 Cube_aux::set_real(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X)
03339 {
03340 arma_extra_debug_sigprint();
03341
03342 typedef typename std::complex<T> eT;
03343 typedef typename ProxyCube<T1>::ea_type ea_type;
03344
03345 const ProxyCube<T1> A(X.get_ref());
03346
03347 arma_debug_assert_same_size
03348 (
03349 out.n_rows, out.n_cols, out.n_slices,
03350 A.get_n_rows(), A.get_n_cols(), A.get_n_slices(),
03351 "Cube::set_real()"
03352 );
03353
03354 const uword n_elem = out.n_elem;
03355 eT* out_mem = out.memptr();
03356 ea_type PA = A.get_ea();
03357
03358 for(uword i=0; i<n_elem; ++i)
03359 {
03360
03361 out_mem[i] = std::complex<T>( PA[i], out_mem[i].imag() );
03362 }
03363 }
03364
03365
03366
03367 template<typename T, typename T1>
03368 inline
03369 void
03370 Cube_aux::set_imag(Cube< std::complex<T> >& out, const BaseCube<T,T1>& X)
03371 {
03372 arma_extra_debug_sigprint();
03373
03374 typedef typename std::complex<T> eT;
03375 typedef typename ProxyCube<T1>::ea_type ea_type;
03376
03377 const ProxyCube<T1> A(X.get_ref());
03378
03379 arma_debug_assert_same_size
03380 (
03381 out.n_rows, out.n_cols, out.n_slices,
03382 A.get_n_rows(), A.get_n_cols(), A.get_n_slices(),
03383 "Cube::set_imag()"
03384 );
03385
03386 const uword n_elem = out.n_elem;
03387 eT* out_mem = out.memptr();
03388 ea_type PA = A.get_ea();
03389
03390 for(uword i=0; i<n_elem; ++i)
03391 {
03392
03393 out_mem[i] = std::complex<T>( out_mem[i].real(), PA[i] );
03394 }
03395 }
03396
03397
03398
03399 #ifdef ARMA_EXTRA_CUBE_MEAT
03400 #include ARMA_INCFILE_WRAP(ARMA_EXTRA_CUBE_MEAT)
03401 #endif
03402
03403
03404