Cube_meat.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2010 NICTA and the authors listed below
00002 // http://nicta.com.au
00003 // 
00004 // Authors:
00005 // - Conrad Sanderson (conradsand at ieee dot org)
00006 // 
00007 // This file is part of the Armadillo C++ library.
00008 // It is provided without any warranty of fitness
00009 // for any purpose. You can redistribute this file
00010 // and/or modify it under the terms of the GNU
00011 // Lesser General Public License (LGPL) as published
00012 // by the Free Software Foundation, either version 3
00013 // of the License or (at your option) any later version.
00014 // (see http://www.opensource.org/licenses for more info)
00015 
00016 
00017 //! \addtogroup Cube
00018 //! @{
00019 
00020 
00021 template<typename eT>
00022 inline
00023 Cube<eT>::~Cube()
00024   {
00025   arma_extra_debug_sigprint_this(this);
00026   
00027   delete_mat();
00028   
00029   if(use_aux_mem == false)
00030     {
00031     if(n_elem > sizeof(mem_local)/sizeof(eT) )
00032       {
00033       delete [] mem;
00034       }
00035     }
00036     
00037   if(arma_config::debug == true)
00038     {
00039     // try to expose buggy user code that accesses deleted objects
00040     access::rw(n_rows)       = 0;
00041     access::rw(n_cols)       = 0;
00042     access::rw(n_elem_slice) = 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   isnt_supported_elem_type<eT>::check();
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   , use_aux_mem(false)
00063   , mat_ptrs(mat_ptrs)
00064   , mem(mem)
00065   {
00066   arma_extra_debug_sigprint_this(this);
00067   }
00068 
00069 
00070 
00071 //! construct the cube to have user specified dimensions
00072 template<typename eT>
00073 inline
00074 Cube<eT>::Cube(const u32 in_n_rows, const u32 in_n_cols, const u32 in_n_slices)
00075   : n_rows(0)
00076   , n_cols(0)
00077   , n_elem_slice(0)
00078   , n_slices(0)
00079   , n_elem(0)
00080   , use_aux_mem(false)
00081   , mat_ptrs(mat_ptrs)
00082   , mem(mem)
00083   {
00084   arma_extra_debug_sigprint_this(this);
00085   
00086   init(in_n_rows, in_n_cols, in_n_slices);
00087   }
00088 
00089 
00090 
00091 //! internal cube construction; if the requested size is small enough, memory from the stack is used.
00092 //! otherwise memory is allocated via 'new'
00093 template<typename eT>
00094 inline
00095 void
00096 Cube<eT>::init(const u32 in_n_rows, const u32 in_n_cols, const u32 in_n_slices)
00097   {
00098   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 );
00099   
00100   const u32 new_n_elem = in_n_rows * in_n_cols * in_n_slices;
00101 
00102   if(n_elem == new_n_elem)
00103     {
00104     if( (n_rows != in_n_rows) || (n_cols != in_n_cols) || (n_slices != in_n_slices) )
00105       {
00106       delete_mat();
00107 
00108       access::rw(n_rows)       = in_n_rows;
00109       access::rw(n_cols)       = in_n_cols;
00110       access::rw(n_elem_slice) = in_n_rows*in_n_cols;
00111       access::rw(n_slices)     = in_n_slices;
00112     
00113       create_mat();
00114       }
00115     }
00116   else
00117     {
00118     arma_debug_check
00119       (
00120       (use_aux_mem == true),
00121       "Cube::init(): can't change the amount of memory as auxiliary memory is in use"
00122       );
00123       
00124     delete_mat();
00125 
00126     if(n_elem > sizeof(mem_local)/sizeof(eT) )
00127       {
00128       delete [] mem;
00129       }
00130     
00131     if(new_n_elem <= sizeof(mem_local)/sizeof(eT) )
00132       {
00133       access::rw(mem) = mem_local;
00134       }
00135     else
00136       {
00137       access::rw(mem) = new(std::nothrow) eT[new_n_elem];
00138       arma_check( (mem == 0), "Cube::init(): out of memory" );
00139       }
00140     
00141     access::rw(n_elem) = new_n_elem;
00142 
00143     if(new_n_elem == 0)
00144       {
00145       access::rw(n_rows)       = 0;
00146       access::rw(n_cols)       = 0;
00147       access::rw(n_elem_slice) = 0;
00148       access::rw(n_slices)     = 0;
00149       }
00150     else
00151       {
00152       access::rw(n_rows)       = in_n_rows;
00153       access::rw(n_cols)       = in_n_cols;
00154       access::rw(n_elem_slice) = in_n_rows*in_n_cols;
00155       access::rw(n_slices)     = in_n_slices;
00156       }
00157       
00158     create_mat();
00159     }
00160   }
00161 
00162 
00163 template<typename eT>
00164 inline
00165 void
00166 Cube<eT>::delete_mat()
00167   {
00168   arma_extra_debug_sigprint();
00169   
00170   for(u32 slice = 0; slice < n_slices; ++slice)
00171     {
00172     delete access::rw(mat_ptrs[slice]);
00173     }
00174 
00175   if(n_slices > sizeof(mat_ptrs_local)/sizeof(Mat<eT>*) )
00176     {
00177     delete [] mat_ptrs;
00178     }
00179   }
00180 
00181 
00182 
00183 template<typename eT>
00184 inline
00185 void
00186 Cube<eT>::create_mat()
00187   {
00188   arma_extra_debug_sigprint();
00189 
00190   if( n_slices <= sizeof(mat_ptrs_local)/sizeof(Mat<eT>*) )
00191     {
00192     access::rw(mat_ptrs) = const_cast< const Mat<eT>** >(mat_ptrs_local);
00193     }
00194   else
00195     {
00196     access::rw(mat_ptrs) = new(std::nothrow) const Mat<eT>*[n_slices];
00197     arma_check( (mat_ptrs == 0), "Cube::create_mat(): out of memory" );
00198     }
00199     
00200   for(u32 slice = 0; slice < n_slices; ++slice)
00201     {
00202     mat_ptrs[slice] = new Mat<eT>('j', slice_memptr(slice), n_rows, n_cols);
00203     }
00204   }
00205 
00206 
00207 
00208 //! Set the cube to be equal to the specified scalar.
00209 //! NOTE: the size of the cube will be 1x1x1
00210 template<typename eT>
00211 arma_inline
00212 const Cube<eT>&
00213 Cube<eT>::operator=(const eT val)
00214   {
00215   arma_extra_debug_sigprint();
00216   
00217   init(1,1,1);
00218   access::rw(mem[0]) = val;
00219   return *this;
00220   }
00221 
00222 
00223 
00224 //! In-place addition of a scalar to all elements of the cube
00225 template<typename eT>
00226 arma_inline
00227 const Cube<eT>&
00228 Cube<eT>::operator+=(const eT val)
00229   {
00230   arma_extra_debug_sigprint();
00231   
00232         eT* local_ptr    = memptr();
00233   const u32 local_n_elem = n_elem;
00234     
00235   u32 i,j;
00236   
00237   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00238     {
00239     local_ptr[i] += val;
00240     local_ptr[j] += val;
00241     }
00242   
00243   if(i < local_n_elem)
00244     {
00245     local_ptr[i] += val;
00246     }
00247   
00248   return *this;
00249   }
00250 
00251 
00252 
00253 //! In-place subtraction of a scalar from all elements of the cube
00254 template<typename eT>
00255 arma_inline
00256 const Cube<eT>&
00257 Cube<eT>::operator-=(const eT val)
00258   {
00259   arma_extra_debug_sigprint();
00260   
00261         eT* local_ptr    = memptr();
00262   const u32 local_n_elem = n_elem;
00263     
00264   u32 i,j;
00265   
00266   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00267     {
00268     local_ptr[i] -= val;
00269     local_ptr[j] -= val;
00270     }
00271   
00272   if(i < local_n_elem)
00273     {
00274     local_ptr[i] -= val;
00275     }
00276   
00277   return *this;
00278   }
00279 
00280 
00281 
00282 //! In-place multiplication of all elements of the cube with a scalar
00283 template<typename eT>
00284 arma_inline
00285 const Cube<eT>&
00286 Cube<eT>::operator*=(const eT val)
00287   {
00288   arma_extra_debug_sigprint();
00289   
00290         eT* local_ptr    = memptr();
00291   const u32 local_n_elem = n_elem;
00292     
00293   u32 i,j;
00294   
00295   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00296     {
00297     local_ptr[i] *= val;
00298     local_ptr[j] *= val;
00299     }
00300   
00301   if(i < local_n_elem)
00302     {
00303     local_ptr[i] *= val;
00304     }
00305   
00306   return *this;
00307   }
00308 
00309 
00310 
00311 //! In-place division of all elements of the cube with a scalar
00312 template<typename eT>
00313 arma_inline
00314 const Cube<eT>&
00315 Cube<eT>::operator/=(const eT val)
00316   {
00317   arma_extra_debug_sigprint();
00318   
00319         eT* local_ptr    = memptr();
00320   const u32 local_n_elem = n_elem;
00321     
00322   u32 i,j;
00323   
00324   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00325     {
00326     local_ptr[i] /= val;
00327     local_ptr[j] /= val;
00328     }
00329   
00330   if(i < local_n_elem)
00331     {
00332     local_ptr[i] /= val;
00333     }
00334   
00335   return *this;
00336   }
00337 
00338 
00339 
00340 //! construct a cube from a given cube
00341 template<typename eT>
00342 inline
00343 Cube<eT>::Cube(const Cube<eT>& in_cube)
00344   : n_rows(0)
00345   , n_cols(0)
00346   , n_elem_slice(0)
00347   , n_slices(0)
00348   , n_elem(0)
00349   , use_aux_mem(false)
00350   , mat_ptrs(mat_ptrs)
00351   , mem(mem)
00352   {
00353   arma_extra_debug_sigprint(arma_boost::format("this = %x   in_cube = %x") % this % &in_cube);
00354   
00355   init(in_cube);
00356   }
00357 
00358 
00359 
00360 //! construct a cube from a given cube
00361 template<typename eT>
00362 inline
00363 const Cube<eT>&
00364 Cube<eT>::operator=(const Cube<eT>& x)
00365   {
00366   arma_extra_debug_sigprint();
00367   
00368   init(x);
00369   return *this;
00370   }
00371 
00372 
00373 
00374 //! construct a cube from a given cube
00375 template<typename eT>
00376 inline
00377 void
00378 Cube<eT>::init(const Cube<eT>& x)
00379   {
00380   arma_extra_debug_sigprint();
00381   
00382   if(this != &x)
00383     {
00384     init(x.n_rows, x.n_cols, x.n_slices);
00385     syslib::copy_elem( memptr(), x.mem, n_elem );
00386     }
00387   }
00388 
00389 
00390 
00391 //! construct a cube from a given auxiliary array of eTs.
00392 //! if copy_aux_mem is true, new memory is allocated and the array is copied.
00393 //! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
00394 //! note that in the latter case 
00395 //! the default is to copy the array.
00396 
00397 template<typename eT>
00398 inline
00399 Cube<eT>::Cube(eT* aux_mem, const u32 aux_n_rows, const u32 aux_n_cols, const u32 aux_n_slices, const bool copy_aux_mem)
00400   : n_rows      (copy_aux_mem ? 0     : aux_n_rows                        )
00401   , n_cols      (copy_aux_mem ? 0     : aux_n_cols                        )
00402   , n_elem_slice(copy_aux_mem ? 0     : aux_n_rows*aux_n_cols             )
00403   , n_slices    (copy_aux_mem ? 0     : aux_n_slices                      )
00404   , n_elem      (copy_aux_mem ? 0     : aux_n_rows*aux_n_cols*aux_n_slices)
00405   , use_aux_mem (copy_aux_mem ? false : true                              )
00406   , mat_ptrs    (mat_ptrs                                                 )
00407   , mem         (copy_aux_mem ? mem   : aux_mem                           )
00408   {
00409   arma_extra_debug_sigprint_this(this);
00410   
00411   if(copy_aux_mem == true)
00412     {
00413     init(aux_n_rows, aux_n_cols, aux_n_slices);
00414     syslib::copy_elem( memptr(), aux_mem, n_elem );
00415     }
00416   else
00417     {
00418     create_mat();
00419     }
00420   }
00421 
00422 
00423 
00424 //! construct a cube from a given auxiliary read-only array of eTs.
00425 //! the array is copied.
00426 template<typename eT>
00427 inline
00428 Cube<eT>::Cube(const eT* aux_mem, const u32 aux_n_rows, const u32 aux_n_cols, const u32 aux_n_slices)
00429   : n_rows(0)
00430   , n_cols(0)
00431   , n_elem_slice(0)
00432   , n_slices(0)
00433   , n_elem(0)
00434   , use_aux_mem(false)
00435   , mat_ptrs(mat_ptrs)
00436   , mem(mem)
00437   {
00438   arma_extra_debug_sigprint_this(this);
00439   
00440   init(aux_n_rows, aux_n_cols, aux_n_slices);
00441   syslib::copy_elem( memptr(), aux_mem, n_elem );
00442   }
00443 
00444 
00445 
00446 //! in-place cube addition
00447 template<typename eT>
00448 inline
00449 const Cube<eT>&
00450 Cube<eT>::operator+=(const Cube<eT>& m)
00451   {
00452   arma_extra_debug_sigprint();
00453   
00454   arma_debug_assert_same_size(*this, m, "cube addition");
00455   
00456   const u32 local_n_elem = m.n_elem;
00457   
00458         eT* out_mem = (*this).memptr();
00459   const eT* m_mem   = m.memptr();
00460   
00461   u32 i,j;
00462   
00463   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00464     {
00465     out_mem[i] += m_mem[i];
00466     out_mem[j] += m_mem[j];
00467     }
00468   
00469   if(i < local_n_elem)
00470     {
00471     out_mem[i] += m_mem[i];
00472     }
00473   
00474   return *this;
00475   }
00476 
00477 
00478 
00479 //! in-place cube subtraction
00480 template<typename eT>
00481 inline
00482 const Cube<eT>&
00483 Cube<eT>::operator-=(const Cube<eT>& m)
00484   {
00485   arma_extra_debug_sigprint();
00486   
00487   arma_debug_assert_same_size(*this, m, "cube subtraction");
00488   
00489   const u32 local_n_elem = m.n_elem;
00490   
00491         eT* out_mem = (*this).memptr();
00492   const eT* m_mem   = m.memptr();
00493   
00494   u32 i,j;
00495   
00496   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00497     {
00498     out_mem[i] -= m_mem[i];
00499     out_mem[j] -= m_mem[j];
00500     }
00501   
00502   if(i < local_n_elem)
00503     {
00504     out_mem[i] -= m_mem[i];
00505     }
00506   
00507   return *this;
00508   }
00509 
00510 
00511 
00512 //! in-place element-wise cube multiplication
00513 template<typename eT>
00514 inline
00515 const Cube<eT>&
00516 Cube<eT>::operator%=(const Cube<eT>& m)
00517   {
00518   arma_extra_debug_sigprint();
00519   
00520   arma_debug_assert_same_size(*this, m, "element-wise cube multiplication");
00521   
00522   const u32 local_n_elem = m.n_elem;
00523   
00524         eT* out_mem = (*this).memptr();
00525   const eT* m_mem   = m.memptr();
00526   
00527   u32 i,j;
00528   
00529   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00530     {
00531     out_mem[i] *= m_mem[i];
00532     out_mem[j] *= m_mem[j];
00533     }
00534   
00535   if(i < local_n_elem)
00536     {
00537     out_mem[i] *= m_mem[i];
00538     }
00539   
00540   return *this;
00541   }
00542 
00543 
00544 
00545 //! in-place element-wise cube division
00546 template<typename eT>
00547 inline
00548 const Cube<eT>&
00549 Cube<eT>::operator/=(const Cube<eT>& m)
00550   {
00551   arma_extra_debug_sigprint();
00552   
00553   arma_debug_assert_same_size(*this, m, "element-wise cube division");
00554   
00555   const u32 local_n_elem = m.n_elem;
00556   
00557         eT* out_mem = (*this).memptr();
00558   const eT* m_mem   = m.memptr();
00559   
00560   u32 i,j;
00561   
00562   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
00563     {
00564     out_mem[i] /= m_mem[i];
00565     out_mem[j] /= m_mem[j];
00566     }
00567   
00568   if(i < local_n_elem)
00569     {
00570     out_mem[i] /= m_mem[i];
00571     }
00572   
00573   return *this;
00574   }
00575 
00576 
00577 
00578 //! for constructing a complex cube out of two non-complex cubes
00579 template<typename eT>
00580 template<typename T1, typename T2>
00581 inline
00582 Cube<eT>::Cube
00583   (
00584   const BaseCube<typename Cube<eT>::pod_type,T1>& A,
00585   const BaseCube<typename Cube<eT>::pod_type,T2>& B
00586   )
00587   : n_rows(0)
00588   , n_cols(0)
00589   , n_elem_slice(0)
00590   , n_slices(0)
00591   , n_elem(0)
00592   , use_aux_mem(false)
00593   , mat_ptrs(mat_ptrs)
00594   , mem(mem)
00595   {
00596   arma_extra_debug_sigprint_this(this);
00597   
00598   arma_type_check< is_complex<eT>::value == false >::apply();   //!< compile-time abort if eT isn't std::complex
00599   
00600   typedef typename T1::elem_type T;
00601   arma_type_check< is_complex<T>::value == true >::apply();   //!< compile-time abort if T is std::complex
00602   
00603   isnt_same_type<std::complex<T>, eT>::check();   //!< compile-time abort if types are not compatible
00604   
00605   const unwrap_cube<T1> tmp_A(A.get_ref());
00606   const unwrap_cube<T2> tmp_B(B.get_ref());
00607   
00608   const Cube<T>& X = tmp_A.M;
00609   const Cube<T>& Y = tmp_B.M;
00610   
00611   arma_assert_same_size(X, Y, "Cube()");
00612   
00613   init(X.n_rows, X.n_cols, X.n_slices);
00614   
00615   const T* X_mem = X.mem;
00616   const T* Y_mem = Y.mem;
00617   
00618   for(u32 i=0; i<n_elem; ++i)
00619     {
00620     access::rw(mem[i]) = std::complex<T>(X_mem[i], Y_mem[i]);
00621     }
00622   }
00623 
00624 
00625 
00626 //! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation)
00627 template<typename eT>
00628 inline
00629 Cube<eT>::Cube(const subview_cube<eT>& X)
00630   : n_rows(0)
00631   , n_cols(0)
00632   , n_elem_slice(0)
00633   , n_slices(0)
00634   , n_elem(0)
00635   , use_aux_mem(false)
00636   , mat_ptrs(mat_ptrs)
00637   , mem(mem)
00638   {
00639   arma_extra_debug_sigprint_this(this);
00640   
00641   this->operator=(X);
00642   }
00643 
00644 
00645 
00646 //! construct a cube from a subview_cube instance (e.g. construct a cube from a delayed subcube operation)
00647 template<typename eT>
00648 inline
00649 const Cube<eT>&
00650 Cube<eT>::operator=(const subview_cube<eT>& X)
00651   {
00652   arma_extra_debug_sigprint();
00653   
00654   subview_cube<eT>::extract(*this, X);
00655   return *this;
00656   }
00657 
00658 
00659 
00660 //! in-place cube addition (using a subcube on the right-hand-side)
00661 template<typename eT>
00662 inline
00663 const Cube<eT>&
00664 Cube<eT>::operator+=(const subview_cube<eT>& X)
00665   {
00666   arma_extra_debug_sigprint();
00667   
00668   subview_cube<eT>::plus_inplace(*this, X);
00669   return *this;
00670   }
00671 
00672 
00673 
00674 //! in-place cube subtraction (using a subcube on the right-hand-side)
00675 template<typename eT>
00676 inline
00677 const Cube<eT>&
00678 Cube<eT>::operator-=(const subview_cube<eT>& X)
00679   {
00680   arma_extra_debug_sigprint();
00681   
00682   subview_cube<eT>::minus_inplace(*this, X);
00683   return *this;
00684   }
00685 
00686 
00687 
00688 //! in-place element-wise cube mutiplication (using a subcube on the right-hand-side)
00689 template<typename eT>
00690 inline
00691 const Cube<eT>&
00692 Cube<eT>::operator%=(const subview_cube<eT>& X)
00693   {
00694   arma_extra_debug_sigprint();
00695   
00696   subview_cube<eT>::schur_inplace(*this, X);
00697   return *this;
00698   }
00699 
00700 
00701 
00702 //! in-place element-wise cube division (using a subcube on the right-hand-side)
00703 template<typename eT>
00704 inline
00705 const Cube<eT>&
00706 Cube<eT>::operator/=(const subview_cube<eT>& X)
00707   {
00708   arma_extra_debug_sigprint();
00709   
00710   subview_cube<eT>::div_inplace(*this, X);
00711   return *this;
00712   }
00713 
00714 
00715 
00716 //! provide the reference to the matrix representing a single slice
00717 template<typename eT>
00718 arma_inline
00719 Mat<eT>&
00720 Cube<eT>::slice(const u32 in_slice)
00721   {
00722   arma_extra_debug_sigprint();
00723   
00724   arma_debug_check
00725     (
00726     (in_slice >= n_slices),
00727     "Cube::slice(): index out of bounds"
00728     );
00729   
00730   return const_cast< Mat<eT>& >( *(mat_ptrs[in_slice]) );
00731   }
00732 
00733 
00734 
00735 //! provide the reference to the matrix representing a single slice
00736 template<typename eT>
00737 arma_inline
00738 const Mat<eT>&
00739 Cube<eT>::slice(const u32 in_slice) const
00740   {
00741   arma_extra_debug_sigprint();
00742   
00743   arma_debug_check
00744     (
00745     (in_slice >= n_slices),
00746     "Cube::slice(): index out of bounds"
00747     );
00748    
00749   return *(mat_ptrs[in_slice]);
00750   }
00751 
00752 
00753 
00754 //! creation of subview_cube (subcube comprised of specified slices)
00755 template<typename eT>
00756 arma_inline
00757 subview_cube<eT>
00758 Cube<eT>::slices(const u32 in_slice1, const u32 in_slice2)
00759   {
00760   arma_extra_debug_sigprint();
00761   
00762   arma_debug_check
00763     (
00764     (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
00765     "Cube::slices(): indices out of bounds or incorrectly used"
00766     );
00767   
00768   return subview_cube<eT>(*this, 0, 0, in_slice1, ( (n_rows>0) ? n_rows-1 : 0 ), ( (n_cols>0) ? n_cols-1 : 0 ), in_slice2);
00769   }
00770 
00771 
00772 
00773 //! creation of subview_cube (subcube comprised of specified slices)
00774 template<typename eT>
00775 arma_inline
00776 const subview_cube<eT>
00777 Cube<eT>::slices(const u32 in_slice1, const u32 in_slice2) const
00778   {
00779   arma_extra_debug_sigprint();
00780   
00781   arma_debug_check
00782     (
00783     (in_slice1 > in_slice2) || (in_slice2 >= n_slices),
00784     "Cube::rows(): indices out of bounds or incorrectly used"
00785     );
00786   
00787   return subview_cube<eT>(*this, 0, 0, in_slice1, ( (n_rows>0) ? n_rows-1 : 0 ), ( (n_cols>0) ? n_cols-1 : 0 ), in_slice2);
00788   }
00789 
00790 
00791 
00792 //! creation of subview_cube (generic subcube)
00793 template<typename eT>
00794 arma_inline
00795 subview_cube<eT>
00796 Cube<eT>::subcube(const u32 in_row1, const u32 in_col1, const u32 in_slice1, const u32 in_row2, const u32 in_col2, const u32 in_slice2)
00797   {
00798   arma_extra_debug_sigprint();
00799   
00800   arma_debug_check
00801     (
00802     (in_row1 >  in_row2) || (in_col1 >  in_col2) || (in_slice1 >  in_slice2) ||
00803     (in_row2 >= n_rows)  || (in_col2 >= n_cols)  || (in_slice2 >= n_slices),
00804     "Cube::subcube(): indices out of bounds or incorrectly used"
00805     );
00806   
00807   return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, in_row2, in_col2, in_slice2);
00808   }
00809 
00810 
00811 
00812 //! creation of subview_cube (generic subcube)
00813 template<typename eT>
00814 arma_inline
00815 const subview_cube<eT>
00816 Cube<eT>::subcube(const u32 in_row1, const u32 in_col1, const u32 in_slice1, const u32 in_row2, const u32 in_col2, const u32 in_slice2) const
00817   {
00818   arma_extra_debug_sigprint();
00819   
00820   arma_debug_check
00821     (
00822     (in_row1 >  in_row2) || (in_col1 >  in_col2) || (in_slice1 >  in_slice2) ||
00823     (in_row2 >= n_rows)  || (in_col2 >= n_cols)  || (in_slice2 >= n_slices),
00824     "Cube::subcube(): indices out of bounds or incorrectly used"
00825     );
00826     
00827   return subview_cube<eT>(*this, in_row1, in_col1, in_slice1, in_row2, in_col2, in_slice2);
00828   }
00829 
00830 
00831 
00832 //! create a cube from OpCube, i.e. run the previously delayed unary operations
00833 template<typename eT>
00834 template<typename T1, typename op_type>
00835 inline
00836 Cube<eT>::Cube(const OpCube<T1, op_type>& X)
00837   : n_rows(0)
00838   , n_cols(0)
00839   , n_elem_slice(0)
00840   , n_slices(0)
00841   , n_elem(0)
00842   , use_aux_mem(false)
00843   , mat_ptrs(mat_ptrs)
00844   , mem(mem)
00845   {
00846   arma_extra_debug_sigprint_this(this);
00847 
00848   isnt_same_type<eT, typename T1::elem_type>::check();
00849   
00850   op_type::apply(*this, X);
00851   }
00852 
00853 
00854 
00855 //! create a cube from OpCube, i.e. run the previously delayed unary operations
00856 template<typename eT>
00857 template<typename T1, typename op_type>
00858 inline
00859 const Cube<eT>&
00860 Cube<eT>::operator=(const OpCube<T1, op_type>& X)
00861   {
00862   arma_extra_debug_sigprint();
00863 
00864   isnt_same_type<eT, typename T1::elem_type>::check();
00865   
00866   op_type::apply(*this, X);
00867   
00868   return *this;
00869   }
00870 
00871 
00872 
00873 //! in-place cube addition, with the right-hand-side operand having delayed operations
00874 template<typename eT>
00875 template<typename T1, typename op_type>
00876 inline
00877 const Cube<eT>&
00878 Cube<eT>::operator+=(const OpCube<T1, op_type>& X)
00879   {
00880   arma_extra_debug_sigprint();
00881   
00882   isnt_same_type<eT, typename T1::elem_type>::check();
00883   
00884   const Cube<eT> m(X);
00885   
00886   return (*this).operator+=(m);
00887   }
00888 
00889 
00890 
00891 //! in-place cube subtraction, with the right-hand-side operand having delayed operations
00892 template<typename eT>
00893 template<typename T1, typename op_type>
00894 inline
00895 const Cube<eT>&
00896 Cube<eT>::operator-=(const OpCube<T1, op_type>& X)
00897   {
00898   arma_extra_debug_sigprint();
00899   
00900   isnt_same_type<eT, typename T1::elem_type>::check();
00901   
00902   const Cube<eT> m(X);
00903   
00904   return (*this).operator-=(m);
00905   }
00906 
00907 
00908 
00909 //! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations
00910 template<typename eT>
00911 template<typename T1, typename op_type>
00912 inline
00913 const Cube<eT>&
00914 Cube<eT>::operator%=(const OpCube<T1, op_type>& X)
00915   {
00916   arma_extra_debug_sigprint();
00917   
00918   isnt_same_type<eT, typename T1::elem_type>::check();
00919   
00920   const Cube<eT> m(X);
00921   
00922   return (*this).operator%=(m);
00923   }
00924 
00925 
00926 
00927 //! in-place cube element-wise division, with the right-hand-side operand having delayed operations
00928 template<typename eT>
00929 template<typename T1, typename op_type>
00930 inline
00931 const Cube<eT>&
00932 Cube<eT>::operator/=(const OpCube<T1, op_type>& X)
00933   {
00934   arma_extra_debug_sigprint();
00935   
00936   isnt_same_type<eT, typename T1::elem_type>::check();
00937   
00938   const Cube<eT> m(X);
00939   
00940   return (*this).operator/=(m);
00941   }
00942 
00943 
00944 
00945 //! create a cube from eOpCube, i.e. run the previously delayed unary operations
00946 template<typename eT>
00947 template<typename T1, typename eop_type>
00948 inline
00949 Cube<eT>::Cube(const eOpCube<T1, eop_type>& X)
00950   : n_rows(0)
00951   , n_cols(0)
00952   , n_elem_slice(0)
00953   , n_slices(0)
00954   , n_elem(0)
00955   , use_aux_mem(false)
00956   , mat_ptrs(mat_ptrs)
00957   , mem(mem)
00958   {
00959   arma_extra_debug_sigprint_this(this);
00960 
00961   isnt_same_type<eT, typename T1::elem_type>::check();
00962   
00963   eop_type::apply(*this, X);
00964   }
00965 
00966 
00967 
00968 //! create a cube from eOpCube, i.e. run the previously delayed unary operations
00969 template<typename eT>
00970 template<typename T1, typename eop_type>
00971 inline
00972 const Cube<eT>&
00973 Cube<eT>::operator=(const eOpCube<T1, eop_type>& X)
00974   {
00975   arma_extra_debug_sigprint();
00976 
00977   isnt_same_type<eT, typename T1::elem_type>::check();
00978   
00979   eop_type::apply(*this, X);
00980   
00981   return *this;
00982   }
00983 
00984 
00985 
00986 //! in-place cube addition, with the right-hand-side operand having delayed operations
00987 template<typename eT>
00988 template<typename T1, typename eop_type>
00989 inline
00990 const Cube<eT>&
00991 Cube<eT>::operator+=(const eOpCube<T1, eop_type>& X)
00992   {
00993   arma_extra_debug_sigprint();
00994   
00995   isnt_same_type<eT, typename T1::elem_type>::check();
00996   
00997   eop_type::apply_inplace_plus(*this, X);
00998   
00999   return *this;
01000   }
01001 
01002 
01003 
01004 //! in-place cube subtraction, with the right-hand-side operand having delayed operations
01005 template<typename eT>
01006 template<typename T1, typename eop_type>
01007 inline
01008 const Cube<eT>&
01009 Cube<eT>::operator-=(const eOpCube<T1, eop_type>& X)
01010   {
01011   arma_extra_debug_sigprint();
01012   
01013   isnt_same_type<eT, typename T1::elem_type>::check();
01014   
01015   eop_type::apply_inplace_minus(*this, X);
01016   
01017   return *this;
01018   }
01019 
01020 
01021 
01022 //! in-place cube element-wise multiplication, with the right-hand-side operand having delayed operations
01023 template<typename eT>
01024 template<typename T1, typename eop_type>
01025 inline
01026 const Cube<eT>&
01027 Cube<eT>::operator%=(const eOpCube<T1, eop_type>& X)
01028   {
01029   arma_extra_debug_sigprint();
01030   
01031   isnt_same_type<eT, typename T1::elem_type>::check();
01032 
01033   eop_type::apply_inplace_schur(*this, X);
01034   
01035   return *this;
01036   }
01037 
01038 
01039 
01040 //! in-place cube element-wise division, with the right-hand-side operand having delayed operations
01041 template<typename eT>
01042 template<typename T1, typename eop_type>
01043 inline
01044 const Cube<eT>&
01045 Cube<eT>::operator/=(const eOpCube<T1, eop_type>& X)
01046   {
01047   arma_extra_debug_sigprint();
01048   
01049   isnt_same_type<eT, typename T1::elem_type>::check();
01050 
01051   eop_type::apply_inplace_div(*this, X);
01052   
01053   return *this;
01054   }
01055 
01056 
01057 
01058 //! create a cube from Glue, i.e. run the previously delayed binary operations
01059 template<typename eT>
01060 template<typename T1, typename T2, typename glue_type>
01061 inline
01062 Cube<eT>::Cube(const GlueCube<T1, T2, glue_type>& X)
01063   : n_rows(0)
01064   , n_cols(0)
01065   , n_elem_slice(0)
01066   , n_slices(0)
01067   , n_elem(0)
01068   , use_aux_mem(false)
01069   , mat_ptrs(mat_ptrs)
01070   , mem(mem)
01071   {
01072   arma_extra_debug_sigprint_this(this);
01073   this->operator=(X);
01074   }
01075 
01076 
01077 
01078 //! create a cube from Glue, i.e. run the previously delayed binary operations
01079 template<typename eT>
01080 template<typename T1, typename T2, typename glue_type>
01081 inline
01082 const Cube<eT>&
01083 Cube<eT>::operator=(const GlueCube<T1, T2, glue_type>& X)
01084   {
01085   arma_extra_debug_sigprint();
01086   
01087   isnt_same_type<eT, typename T1::elem_type>::check();
01088   isnt_same_type<eT, typename T2::elem_type>::check();
01089   
01090   glue_type::apply(*this, X);
01091   
01092   return *this;
01093   }
01094 
01095 
01096 //! in-place cube addition, with the right-hand-side operands having delayed operations
01097 template<typename eT>
01098 template<typename T1, typename T2, typename glue_type>
01099 inline
01100 const Cube<eT>&
01101 Cube<eT>::operator+=(const GlueCube<T1, T2, glue_type>& X)
01102   {
01103   arma_extra_debug_sigprint();
01104   
01105   isnt_same_type<eT, typename T1::elem_type>::check();
01106   isnt_same_type<eT, typename T2::elem_type>::check();
01107   
01108   const Cube<eT> m(X);
01109   
01110   return (*this).operator+=(m);
01111   }
01112 
01113 
01114 
01115 //! in-place cube subtraction, with the right-hand-side operands having delayed operations
01116 template<typename eT>
01117 template<typename T1, typename T2, typename glue_type>
01118 inline
01119 const Cube<eT>&
01120 Cube<eT>::operator-=(const GlueCube<T1, T2, glue_type>& X)
01121   {
01122   arma_extra_debug_sigprint();
01123   
01124   isnt_same_type<eT, typename T1::elem_type>::check();
01125   isnt_same_type<eT, typename T2::elem_type>::check();
01126   
01127   const Cube<eT> m(X);
01128   
01129   return (*this).operator-=(m);
01130   }
01131 
01132 
01133 
01134 //! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations
01135 template<typename eT>
01136 template<typename T1, typename T2, typename glue_type>
01137 inline
01138 const Cube<eT>&
01139 Cube<eT>::operator%=(const GlueCube<T1, T2, glue_type>& X)
01140   {
01141   arma_extra_debug_sigprint();
01142   
01143   isnt_same_type<eT, typename T1::elem_type>::check();
01144   isnt_same_type<eT, typename T2::elem_type>::check();
01145   
01146   const Cube<eT> m(X);
01147   
01148   return (*this).operator%=(m);
01149   }
01150 
01151 
01152 
01153 //! in-place cube element-wise division, with the right-hand-side operands having delayed operations
01154 template<typename eT>
01155 template<typename T1, typename T2, typename glue_type>
01156 inline
01157 const Cube<eT>&
01158 Cube<eT>::operator/=(const GlueCube<T1, T2, glue_type>& X)
01159   {
01160   arma_extra_debug_sigprint();
01161   
01162   isnt_same_type<eT, typename T1::elem_type>::check();
01163   isnt_same_type<eT, typename T2::elem_type>::check();
01164   
01165   const Cube<eT> m(X);
01166   
01167   return (*this).operator/=(m);
01168   }
01169 
01170 
01171 
01172 //! create a cube from eGlue, i.e. run the previously delayed binary operations
01173 template<typename eT>
01174 template<typename T1, typename T2, typename eglue_type>
01175 inline
01176 Cube<eT>::Cube(const eGlueCube<T1, T2, eglue_type>& X)
01177   : n_rows(0)
01178   , n_cols(0)
01179   , n_elem_slice(0)
01180   , n_slices(0)
01181   , n_elem(0)
01182   , use_aux_mem(false)
01183   , mat_ptrs(mat_ptrs)
01184   , mem(mem)
01185   {
01186   arma_extra_debug_sigprint_this(this);
01187   this->operator=(X);
01188   }
01189 
01190 
01191 
01192 //! create a cube from Glue, i.e. run the previously delayed binary operations
01193 template<typename eT>
01194 template<typename T1, typename T2, typename eglue_type>
01195 inline
01196 const Cube<eT>&
01197 Cube<eT>::operator=(const eGlueCube<T1, T2, eglue_type>& X)
01198   {
01199   arma_extra_debug_sigprint();
01200   
01201   isnt_same_type<eT, typename T1::elem_type>::check();
01202   isnt_same_type<eT, typename T2::elem_type>::check();
01203   
01204   eglue_type::apply(*this, X);
01205   
01206   return *this;
01207   }
01208 
01209 
01210 //! in-place cube addition, with the right-hand-side operands having delayed operations
01211 template<typename eT>
01212 template<typename T1, typename T2, typename eglue_type>
01213 inline
01214 const Cube<eT>&
01215 Cube<eT>::operator+=(const eGlueCube<T1, T2, eglue_type>& X)
01216   {
01217   arma_extra_debug_sigprint();
01218   
01219   isnt_same_type<eT, typename T1::elem_type>::check();
01220   isnt_same_type<eT, typename T2::elem_type>::check();
01221   
01222   eglue_type::apply_inplace_plus(*this, X);
01223   
01224   return *this;
01225   }
01226 
01227 
01228 
01229 //! in-place cube subtraction, with the right-hand-side operands having delayed operations
01230 template<typename eT>
01231 template<typename T1, typename T2, typename eglue_type>
01232 inline
01233 const Cube<eT>&
01234 Cube<eT>::operator-=(const eGlueCube<T1, T2, eglue_type>& X)
01235   {
01236   arma_extra_debug_sigprint();
01237   
01238   isnt_same_type<eT, typename T1::elem_type>::check();
01239   isnt_same_type<eT, typename T2::elem_type>::check();
01240   
01241   eglue_type::apply_inplace_minus(*this, X);
01242   
01243   return *this;
01244   }
01245 
01246 
01247 
01248 //! in-place cube element-wise multiplication, with the right-hand-side operands having delayed operations
01249 template<typename eT>
01250 template<typename T1, typename T2, typename eglue_type>
01251 inline
01252 const Cube<eT>&
01253 Cube<eT>::operator%=(const eGlueCube<T1, T2, eglue_type>& X)
01254   {
01255   arma_extra_debug_sigprint();
01256   
01257   isnt_same_type<eT, typename T1::elem_type>::check();
01258   isnt_same_type<eT, typename T2::elem_type>::check();
01259   
01260   eglue_type::apply_inplace_schur(*this, X);
01261   
01262   return *this;
01263   }
01264 
01265 
01266 
01267 //! in-place cube element-wise division, with the right-hand-side operands having delayed operations
01268 template<typename eT>
01269 template<typename T1, typename T2, typename eglue_type>
01270 inline
01271 const Cube<eT>&
01272 Cube<eT>::operator/=(const eGlueCube<T1, T2, eglue_type>& X)
01273   {
01274   arma_extra_debug_sigprint();
01275   
01276   isnt_same_type<eT, typename T1::elem_type>::check();
01277   isnt_same_type<eT, typename T2::elem_type>::check();
01278   
01279   eglue_type::apply_inplace_div(*this, X);
01280   
01281   return *this;
01282   }
01283 
01284 
01285 
01286 //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
01287 template<typename eT>
01288 arma_inline
01289 eT&
01290 Cube<eT>::operator() (const u32 i)
01291   {
01292   arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
01293   return access::rw(mem[i]);
01294   }
01295 
01296 
01297 
01298 //! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
01299 template<typename eT>
01300 arma_inline
01301 eT
01302 Cube<eT>::operator() (const u32 i) const
01303   {
01304   arma_debug_check( (i >= n_elem), "Cube::operator(): index out of bounds");
01305   return mem[i];
01306   }
01307 
01308 
01309 //! linear element accessor (treats the cube as a vector); no bounds check.  
01310 template<typename eT>
01311 arma_inline
01312 eT&
01313 Cube<eT>::operator[] (const u32 i)
01314   {
01315   return access::rw(mem[i]);
01316   }
01317 
01318 
01319 
01320 //! linear element accessor (treats the cube as a vector); no bounds check
01321 template<typename eT>
01322 arma_inline
01323 eT
01324 Cube<eT>::operator[] (const u32 i) const
01325   {
01326   return mem[i];
01327   }
01328 
01329 
01330 
01331 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
01332 template<typename eT>
01333 arma_inline
01334 eT&
01335 Cube<eT>::operator() (const u32 in_row, const u32 in_col, const u32 in_slice)
01336   {
01337   arma_debug_check
01338     (
01339     (in_row >= n_rows) ||
01340     (in_col >= n_cols) ||
01341     (in_slice >= n_slices)
01342     ,
01343     "Cube::operator(): index out of bounds"
01344     );
01345 
01346   return access::rw(mem[in_slice*n_elem_slice + in_col*n_rows + in_row]);
01347   }
01348 
01349 
01350 
01351 //! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
01352 template<typename eT>
01353 arma_inline
01354 eT
01355 Cube<eT>::operator() (const u32 in_row, const u32 in_col, const u32 in_slice) const
01356   {
01357   arma_debug_check
01358     (
01359     (in_row >= n_rows) ||
01360     (in_col >= n_cols) ||
01361     (in_slice >= n_slices)
01362     ,
01363     "Cube::operator(): index out of bounds"
01364     );
01365 
01366   return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
01367   }
01368 
01369 
01370 
01371 //! element accessor; no bounds check
01372 template<typename eT>
01373 arma_inline
01374 eT&
01375 Cube<eT>::at(const u32 in_row, const u32 in_col, const u32 in_slice)
01376   {
01377   return access::rw( mem[in_slice*n_elem_slice + in_col*n_rows + in_row] );
01378   }
01379 
01380 
01381 
01382 //! element accessor; no bounds check
01383 template<typename eT>
01384 arma_inline
01385 eT
01386 Cube<eT>::at(const u32 in_row, const u32 in_col, const u32 in_slice) const
01387   {
01388   return mem[in_slice*n_elem_slice + in_col*n_rows + in_row];
01389   }
01390 
01391 
01392 
01393 //! prefix ++
01394 template<typename eT>
01395 arma_inline
01396 const Cube<eT>&
01397 Cube<eT>::operator++()
01398   {
01399   Cube_aux::prefix_pp(*this);
01400   return *this;
01401   }
01402 
01403 
01404 
01405 //! postfix ++  (must not return the object by reference)
01406 template<typename eT>
01407 arma_inline
01408 void
01409 Cube<eT>::operator++(int)
01410   {
01411   Cube_aux::postfix_pp(*this);
01412   }
01413 
01414 
01415 
01416 //! prefix --
01417 template<typename eT>
01418 arma_inline
01419 const Cube<eT>&
01420 Cube<eT>::operator--()
01421   {
01422   Cube_aux::prefix_mm(*this);
01423   return *this;
01424   }
01425 
01426 
01427 
01428 //! postfix --  (must not return the object by reference)
01429 template<typename eT>
01430 arma_inline
01431 void
01432 Cube<eT>::operator--(int)
01433   {
01434   Cube_aux::postfix_mm(*this);
01435   }
01436 
01437 
01438 
01439 //! returns true if all of the elements are finite
01440 template<typename eT>
01441 arma_inline
01442 bool
01443 Cube<eT>::is_finite() const
01444   {
01445   for(u32 i=0; i<n_elem; ++i)
01446     {
01447     if(arma_isfinite(mem[i]) == false)
01448       {
01449       return false;
01450       }
01451     }
01452 
01453   return true;
01454   }
01455 
01456 
01457 
01458 //! returns a pointer to array of eTs used by the cube
01459 template<typename eT>
01460 arma_inline
01461 eT*
01462 Cube<eT>::memptr()
01463   {
01464   return const_cast<eT*>(mem);
01465   }
01466 
01467 
01468 
01469 //! returns a pointer to array of eTs used by the cube
01470 template<typename eT>
01471 arma_inline
01472 const eT*
01473 Cube<eT>::memptr() const
01474   {
01475   return mem;
01476   }
01477 
01478 
01479 
01480 //! returns a pointer to array of eTs used by the specified slice in the cube
01481 template<typename eT>
01482 arma_inline
01483 eT*
01484 Cube<eT>::slice_memptr(const u32 slice)
01485   {
01486   return const_cast<eT*>( &mem[ slice*n_elem_slice ] );
01487   }
01488 
01489 
01490 
01491 //! returns a pointer to array of eTs used by the specified slice in the cube
01492 template<typename eT>
01493 arma_inline
01494 const eT*
01495 Cube<eT>::slice_memptr(const u32 slice) const
01496   {
01497   return &mem[ slice*n_elem_slice ];
01498   }
01499 
01500 
01501 
01502 //! returns a pointer to array of eTs used by the specified slice in the cube
01503 template<typename eT>
01504 arma_inline
01505 eT*
01506 Cube<eT>::slice_colptr(const u32 slice, const u32 col)
01507   {
01508   return const_cast<eT*>( &mem[ slice*n_elem_slice + col*n_rows] );
01509   }
01510 
01511 
01512 
01513 //! returns a pointer to array of eTs used by the specified slice in the cube
01514 template<typename eT>
01515 arma_inline
01516 const eT*
01517 Cube<eT>::slice_colptr(const u32 slice, const u32 col) const
01518   {
01519   return &mem[ slice*n_elem_slice + col*n_rows ];
01520   }
01521 
01522 
01523 
01524 //! print contents of the cube (to the cout stream),
01525 //! optionally preceding with a user specified line of text.
01526 //! the precision and cell width are modified.
01527 //! on return, the stream's flags are restored to their original values.
01528 template<typename eT>
01529 inline
01530 void
01531 Cube<eT>::print(const std::string extra_text) const
01532   {
01533   arma_extra_debug_sigprint();
01534   
01535   if(extra_text.length() != 0)
01536     {
01537     cout << extra_text << '\n';
01538     }
01539   
01540   arma_ostream::print(cout, *this, true);
01541   }
01542 
01543 
01544 //! print contents of the cube to a user specified stream,
01545 //! optionally preceding with a user specified line of text.
01546 //! the precision and cell width are modified.
01547 //! on return, the stream's flags are restored to their original values.
01548 template<typename eT>
01549 inline
01550 void
01551 Cube<eT>::print(std::ostream& user_stream, const std::string extra_text) const
01552   {
01553   arma_extra_debug_sigprint();
01554   
01555   if(extra_text.length() != 0)
01556     {
01557     user_stream << extra_text << '\n';
01558     }
01559   
01560   arma_ostream::print(user_stream, *this, true);
01561   }
01562 
01563 
01564 
01565 //! print contents of the cube (to the cout stream),
01566 //! optionally preceding with a user specified line of text.
01567 //! the stream's flags are used as is and are not modified
01568 //! (i.e. the precision and cell width are not modified).
01569 template<typename eT>
01570 inline
01571 void
01572 Cube<eT>::raw_print(const std::string extra_text) const
01573   {
01574   arma_extra_debug_sigprint();
01575   
01576   if(extra_text.length() != 0)
01577     {
01578     cout << extra_text << '\n';
01579     }
01580   
01581   arma_ostream::print(cout, *this, false);
01582   }
01583 
01584 
01585 
01586 //! print contents of the cube to a user specified stream,
01587 //! optionally preceding with a user specified line of text.
01588 //! the stream's flags are used as is and are not modified.
01589 //! (i.e. the precision and cell width are not modified).
01590 template<typename eT>
01591 inline
01592 void
01593 Cube<eT>::raw_print(std::ostream& user_stream, const std::string extra_text) const
01594   {
01595   arma_extra_debug_sigprint();
01596   
01597   if(extra_text.length() != 0)
01598     {
01599     user_stream << extra_text << '\n';
01600     }
01601   
01602   arma_ostream::print(user_stream, *this, false);
01603   }
01604 
01605 
01606 
01607 //! change the cube to have user specified dimensions (data is not preserved)
01608 template<typename eT>
01609 inline
01610 void
01611 Cube<eT>::set_size(const u32 in_n_rows, const u32 in_n_cols, const u32 in_n_slices)
01612   {
01613   arma_extra_debug_sigprint();
01614   
01615   init(in_n_rows, in_n_cols, in_n_slices);
01616   }
01617 
01618 
01619 
01620 //! change the cube (without preserving data) to have the same dimensions as the given cube 
01621 template<typename eT>
01622 template<typename eT2>
01623 inline
01624 void
01625 Cube<eT>::copy_size(const Cube<eT2>& m)
01626   {
01627   arma_extra_debug_sigprint();
01628   
01629   init(m.n_rows, m.n_cols, m.n_slices);
01630   }
01631 
01632 
01633 
01634 //! fill the cube with the specified value
01635 template<typename eT>
01636 inline
01637 void
01638 Cube<eT>::fill(const eT val)
01639   {
01640   arma_extra_debug_sigprint();
01641   
01642         eT* local_ptr    = memptr();
01643   const u32 local_n_elem = n_elem;
01644   
01645   u32 i,j;
01646   
01647   for(i=0, j=1; j<local_n_elem; i+=2, j+=2)
01648     {
01649     local_ptr[i] = val;
01650     local_ptr[j] = val;
01651     }
01652   
01653   if(i < local_n_elem)
01654     {
01655     local_ptr[i] = val;
01656     }
01657   }
01658 
01659 
01660 
01661 template<typename eT>
01662 inline
01663 void
01664 Cube<eT>::zeros()
01665   {
01666   arma_extra_debug_sigprint();
01667   
01668   fill(eT(0));
01669   }
01670 
01671 
01672 
01673 template<typename eT>
01674 inline
01675 void
01676 Cube<eT>::zeros(const u32 in_rows, const u32 in_cols, const u32 in_slices)
01677   {
01678   arma_extra_debug_sigprint( arma_boost::format("in_rows = %d, in_cols = %d, in_slices = %d") % in_rows % in_cols % in_slices );
01679 
01680   set_size(in_rows, in_cols, in_slices);
01681   fill(eT(0));
01682   }
01683 
01684 
01685 
01686 template<typename eT>
01687 inline
01688 void
01689 Cube<eT>::ones()
01690   {
01691   arma_extra_debug_sigprint();
01692   
01693   fill(eT(1));
01694   }
01695 
01696 
01697 
01698 template<typename eT>
01699 inline
01700 void
01701 Cube<eT>::ones(const u32 in_rows, const u32 in_cols, const u32 in_slices)
01702   {
01703   arma_extra_debug_sigprint( arma_boost::format("in_rows = %d, in_cols = %d, in_slices = %d") % in_rows % in_cols % in_slices );
01704 
01705   set_size(in_rows, in_cols, in_slices);
01706   fill(eT(1));
01707   }
01708 
01709 
01710 
01711 template<typename eT>
01712 inline
01713 void
01714 Cube<eT>::reset()
01715   {
01716   arma_extra_debug_sigprint();
01717   
01718   init(0,0,0);
01719   }
01720 
01721 
01722 
01723 //! save the cube to a file
01724 template<typename eT>
01725 inline
01726 bool
01727 Cube<eT>::save(const std::string name, const file_type type, const bool print_status) const
01728   {
01729   arma_extra_debug_sigprint();
01730   
01731   bool save_okay;
01732   
01733   switch(type)
01734     {
01735     case raw_ascii:
01736       save_okay = diskio::save_raw_ascii(*this, name);
01737       break;
01738     
01739     case arma_ascii:
01740       save_okay = diskio::save_arma_ascii(*this, name);
01741       break;
01742     
01743     case arma_binary:
01744       save_okay = diskio::save_arma_binary(*this, name);
01745       break;
01746       
01747     case ppm_binary:
01748       save_okay = diskio::save_ppm_binary(*this, name);
01749       break;
01750 
01751     default:
01752       arma_warn(print_status, "Cube::save(): unsupported file type");
01753       save_okay = false;
01754     }
01755   
01756   arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to ", name);
01757   
01758   return save_okay;
01759   }
01760 
01761 
01762 
01763 //! save the cube to a stream
01764 template<typename eT>
01765 inline
01766 bool
01767 Cube<eT>::save(std::ostream& os, const file_type type, const bool print_status) const
01768   {
01769   arma_extra_debug_sigprint();
01770   
01771   bool save_okay;
01772   
01773   switch(type)
01774     {
01775     case raw_ascii:
01776       save_okay = diskio::save_raw_ascii(*this, os);
01777       break;
01778     
01779     case arma_ascii:
01780       save_okay = diskio::save_arma_ascii(*this, os);
01781       break;
01782     
01783     case arma_binary:
01784       save_okay = diskio::save_arma_binary(*this, os);
01785       break;
01786       
01787     case ppm_binary:
01788       save_okay = diskio::save_ppm_binary(*this, os);
01789       break;
01790 
01791     default:
01792       arma_warn(print_status, "Cube::save(): unsupported file type");
01793       save_okay = false;
01794     }
01795   
01796   arma_warn( (print_status && (save_okay == false)), "Cube::save(): couldn't write to given stream");
01797   
01798   return save_okay;
01799   }
01800 
01801 
01802 
01803 //! load a cube from a file
01804 template<typename eT>
01805 inline
01806 bool
01807 Cube<eT>::load(const std::string name, const file_type type, const bool print_status)
01808   {
01809   arma_extra_debug_sigprint();
01810   
01811   bool load_okay;
01812   std::string err_msg;
01813   
01814   switch(type)
01815     {
01816     case auto_detect:
01817       load_okay = diskio::load_auto_detect(*this, name, err_msg);
01818       break;
01819     
01820     case raw_ascii:
01821       load_okay = diskio::load_raw_ascii(*this, name, err_msg);
01822       break;
01823     
01824     case arma_ascii:
01825       load_okay = diskio::load_arma_ascii(*this, name, err_msg);
01826       break;
01827     
01828     case arma_binary:
01829       load_okay = diskio::load_arma_binary(*this, name, err_msg);
01830       break;
01831       
01832     case ppm_binary:
01833       load_okay = diskio::load_ppm_binary(*this, name, err_msg);
01834       break;
01835 
01836     default:
01837       arma_warn(print_status, "Cube::load(): unsupported file type");
01838       load_okay = false;
01839     }
01840   
01841   if( (print_status == true) && (load_okay == false) )
01842     {
01843     if(err_msg.length() > 0)
01844       {
01845       arma_print("Cube::load(): ", err_msg, name);
01846       }
01847     else
01848       {
01849       arma_print("Cube::load(): couldn't read ", name);
01850       }
01851     }
01852   
01853   if(load_okay == false)
01854     {
01855     (*this).reset();
01856     }
01857     
01858   return load_okay;
01859   }
01860 
01861 
01862 
01863 //! load a cube from a stream
01864 template<typename eT>
01865 inline
01866 bool
01867 Cube<eT>::load(std::istream& is, const file_type type, const bool print_status)
01868   {
01869   arma_extra_debug_sigprint();
01870   
01871   bool load_okay;
01872   std::string err_msg;
01873   
01874   switch(type)
01875     {
01876     case auto_detect:
01877       load_okay = diskio::load_auto_detect(*this, is, err_msg);
01878       break;
01879     
01880     case raw_ascii:
01881       load_okay = diskio::load_raw_ascii(*this, is, err_msg);
01882       break;
01883     
01884     case arma_ascii:
01885       load_okay = diskio::load_arma_ascii(*this, is, err_msg);
01886       break;
01887     
01888     case arma_binary:
01889       load_okay = diskio::load_arma_binary(*this, is, err_msg);
01890       break;
01891       
01892     case ppm_binary:
01893       load_okay = diskio::load_ppm_binary(*this, is, err_msg);
01894       break;
01895     
01896     default:
01897       arma_warn(print_status, "Cube::load(): unsupported file type");
01898       load_okay = false;
01899     }
01900   
01901   
01902   if( (print_status == true) && (load_okay == false) )
01903     {
01904     if(err_msg.length() > 0)
01905       {
01906       arma_print("Cube::load(): ", err_msg, "the given stream");
01907       }
01908     else
01909       {
01910       arma_print("Cube::load(): couldn't load from the given stream");
01911       }
01912     }
01913   
01914   if(load_okay == false)
01915     {
01916     (*this).reset();
01917     }
01918     
01919   return load_okay;
01920   }
01921 
01922 
01923 
01924 //! save the cube to a file, without printing any error messages
01925 template<typename eT>
01926 inline
01927 bool
01928 Cube<eT>::quiet_save(const std::string name, const file_type type) const
01929   {
01930   arma_extra_debug_sigprint();
01931   
01932   return (*this).save(name, type, false);
01933   }
01934 
01935 
01936 
01937 //! save the cube to a stream, without printing any error messages
01938 template<typename eT>
01939 inline
01940 bool
01941 Cube<eT>::quiet_save(std::ostream& os, const file_type type) const
01942   {
01943   arma_extra_debug_sigprint();
01944   
01945   return (*this).save(os, type, false);
01946   }
01947 
01948 
01949 
01950 //! load a cube from a file, without printing any error messages
01951 template<typename eT>
01952 inline
01953 bool
01954 Cube<eT>::quiet_load(const std::string name, const file_type type)
01955   {
01956   arma_extra_debug_sigprint();
01957   
01958   return (*this).load(name, type, false);
01959   }
01960 
01961 
01962 
01963 //! load a cube from a stream, without printing any error messages
01964 template<typename eT>
01965 inline
01966 bool
01967 Cube<eT>::quiet_load(std::istream& is, const file_type type)
01968   {
01969   arma_extra_debug_sigprint();
01970   
01971   return (*this).load(is, type, false);
01972   }
01973 
01974 
01975 
01976 template<typename eT>
01977 inline
01978 typename Cube<eT>::iterator
01979 Cube<eT>::begin()
01980   {
01981   arma_extra_debug_sigprint();
01982   
01983   return memptr();
01984   }
01985 
01986 
01987 
01988 template<typename eT>
01989 inline
01990 typename Cube<eT>::const_iterator
01991 Cube<eT>::begin() const
01992   {
01993   arma_extra_debug_sigprint();
01994   
01995   return memptr();
01996   }
01997 
01998 
01999 
02000 template<typename eT>
02001 inline
02002 typename Cube<eT>::iterator
02003 Cube<eT>::end()
02004   {
02005   arma_extra_debug_sigprint();
02006   
02007   return memptr() + n_elem;
02008   }
02009 
02010 
02011 
02012 template<typename eT>
02013 inline
02014 typename Cube<eT>::const_iterator
02015 Cube<eT>::end() const
02016   {
02017   arma_extra_debug_sigprint();
02018   
02019   return memptr() + n_elem;
02020   }
02021   
02022 
02023 
02024 template<typename eT>
02025 inline
02026 typename Cube<eT>::slice_iterator
02027 Cube<eT>::begin_slice(const u32 slice_num)
02028   {
02029   arma_extra_debug_sigprint();
02030   
02031   arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
02032   
02033   return slice_memptr(slice_num);
02034   }
02035 
02036 
02037 
02038 template<typename eT>
02039 inline
02040 typename Cube<eT>::const_slice_iterator
02041 Cube<eT>::begin_slice(const u32 slice_num) const
02042   {
02043   arma_extra_debug_sigprint();
02044   
02045   arma_debug_check( (slice_num >= n_slices), "begin_slice(): index out of bounds");
02046   
02047   return slice_memptr(slice_num);
02048   }
02049 
02050 
02051 
02052 template<typename eT>
02053 inline
02054 typename Cube<eT>::slice_iterator
02055 Cube<eT>::end_slice(const u32 slice_num)
02056   {
02057   arma_extra_debug_sigprint();
02058   
02059   arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
02060   
02061   return slice_memptr(slice_num) + n_elem_slice;
02062   }
02063 
02064 
02065 
02066 template<typename eT>
02067 inline
02068 typename Cube<eT>::const_slice_iterator
02069 Cube<eT>::end_slice(const u32 slice_num) const
02070   {
02071   arma_extra_debug_sigprint();
02072   
02073   arma_debug_check( (slice_num >= n_slices), "end_slice(): index out of bounds");
02074   
02075   return slice_memptr(slice_num) + n_elem_slice;
02076   }
02077 
02078 
02079 
02080 //! prefix ++
02081 template<typename eT>
02082 arma_inline
02083 void
02084 Cube_aux::prefix_pp(Cube<eT>& x)
02085   {
02086         eT* memptr = x.memptr();
02087   const u32 n_elem = x.n_elem;
02088   
02089   u32 i,j;
02090 
02091   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02092     {
02093     ++(memptr[i]);
02094     ++(memptr[j]);
02095     }
02096   
02097   if(i < n_elem)
02098     {
02099     ++(memptr[i]);
02100     }
02101   }
02102 
02103 
02104 
02105 //! prefix ++ for complex numbers (work around for limitations of the std::complex class)
02106 template<typename T>
02107 arma_inline
02108 void
02109 Cube_aux::prefix_pp(Cube< std::complex<T> >& x)
02110   {
02111   x += T(1);
02112   }
02113 
02114 
02115 
02116 //! postfix ++
02117 template<typename eT>
02118 arma_inline
02119 void
02120 Cube_aux::postfix_pp(Cube<eT>& x)
02121   {
02122         eT* memptr = x.memptr();
02123   const u32 n_elem = x.n_elem;
02124   
02125   u32 i,j;
02126   
02127   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02128     {
02129     (memptr[i])++;
02130     (memptr[j])++;
02131     }
02132   
02133   if(i < n_elem)
02134     {
02135     (memptr[i])++;
02136     }
02137   }
02138 
02139 
02140 
02141 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
02142 template<typename T>
02143 arma_inline
02144 void
02145 Cube_aux::postfix_pp(Cube< std::complex<T> >& x)
02146   {
02147   x += T(1);
02148   }
02149 
02150 
02151 
02152 //! prefix --
02153 template<typename eT>
02154 arma_inline
02155 void
02156 Cube_aux::prefix_mm(Cube<eT>& x)
02157   {
02158         eT* memptr = x.memptr();
02159   const u32 n_elem = x.n_elem;
02160 
02161   u32 i,j;
02162 
02163   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02164     {
02165     --(memptr[i]);
02166     --(memptr[j]);
02167     }
02168   
02169   if(i < n_elem)
02170     {
02171     --(memptr[i]);
02172     }
02173   }
02174 
02175 
02176 
02177 //! prefix -- for complex numbers (work around for limitations of the std::complex class)
02178 template<typename T>
02179 arma_inline
02180 void
02181 Cube_aux::prefix_mm(Cube< std::complex<T> >& x)
02182   {
02183   x -= T(1);
02184   }
02185 
02186 
02187 
02188 //! postfix --
02189 template<typename eT>
02190 arma_inline
02191 void
02192 Cube_aux::postfix_mm(Cube<eT>& x)
02193   {
02194         eT* memptr = x.memptr();
02195   const u32 n_elem = x.n_elem;
02196 
02197   u32 i,j;
02198 
02199   for(i=0, j=1; j<n_elem; i+=2, j+=2)
02200     {
02201     (memptr[i])--;
02202     (memptr[j])--;
02203     }
02204   
02205   if(i < n_elem)
02206     {
02207     (memptr[i])--;
02208     }
02209   }
02210 
02211 
02212 
02213 //! postfix ++ for complex numbers (work around for limitations of the std::complex class)
02214 template<typename T>
02215 arma_inline
02216 void
02217 Cube_aux::postfix_mm(Cube< std::complex<T> >& x)
02218   {
02219   x -= T(1);
02220   }
02221 
02222 
02223 
02224 //! @}