$search
00001 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2008-2011 Conrad Sanderson 00003 // 00004 // This file is part of the Armadillo C++ library. 00005 // It is provided without any warranty of fitness 00006 // for any purpose. You can redistribute this file 00007 // and/or modify it under the terms of the GNU 00008 // Lesser General Public License (LGPL) as published 00009 // by the Free Software Foundation, either version 3 00010 // of the License or (at your option) any later version. 00011 // (see http://www.opensource.org/licenses for more info) 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 // try to expose buggy user code that accesses deleted objects 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 // insertion at slice_num == n_slices is in effect an append operation 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 //out.slices(slice_num, slice_num + N - 1).zeros(); 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 // insertion at slice_num == n_slices is in effect an append operation 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 //out_mem[i].real() = PA[i]; 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 //out_mem[i].imag() = PA[i]; 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