subview_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 subview_cube
00018 //! @{
00019 
00020 
00021 template<typename eT>
00022 inline
00023 subview_cube<eT>::~subview_cube()
00024   {
00025   arma_extra_debug_sigprint();
00026   }
00027 
00028 
00029 
00030 template<typename eT>
00031 arma_inline
00032 subview_cube<eT>::subview_cube
00033   (
00034   const Cube<eT>& in_m,
00035   const u32       in_row1,
00036   const u32       in_col1,
00037   const u32       in_slice1,
00038   const u32       in_row2,
00039   const u32       in_col2,
00040   const u32       in_slice2
00041   )
00042   : m           (in_m)
00043   , m_ptr       (0)
00044   , aux_row1    (in_row1)
00045   , aux_col1    (in_col1)
00046   , aux_slice1  (in_slice1)
00047   , aux_row2    (in_row2)
00048   , aux_col2    (in_col2)
00049   , aux_slice2  (in_slice2)
00050   , n_rows      (1 + in_row2 - in_row1)
00051   , n_cols      (1 + in_col2 - in_col1)
00052   , n_elem_slice(n_rows * n_cols)
00053   , n_slices    (1 + in_slice2 - in_slice1)
00054   , n_elem      (n_elem_slice * n_slices)
00055   {
00056   arma_extra_debug_sigprint();
00057   }
00058 
00059 
00060 
00061 template<typename eT>
00062 arma_inline
00063 subview_cube<eT>::subview_cube
00064   (
00065         Cube<eT>& in_m,
00066   const u32       in_row1,
00067   const u32       in_col1,
00068   const u32       in_slice1,
00069   const u32       in_row2,
00070   const u32       in_col2,
00071   const u32       in_slice2
00072   )
00073   : m           (in_m)
00074   , m_ptr       (&in_m)
00075   , aux_row1    (in_row1)
00076   , aux_col1    (in_col1)
00077   , aux_slice1  (in_slice1)
00078   , aux_row2    (in_row2)
00079   , aux_col2    (in_col2)
00080   , aux_slice2  (in_slice2)
00081   , n_rows      (1 + in_row2 - in_row1)
00082   , n_cols      (1 + in_col2 - in_col1)
00083   , n_elem_slice(n_rows * n_cols)
00084   , n_slices    (1 + in_slice2 - in_slice1)
00085   , n_elem      (n_elem_slice * n_slices)
00086   {
00087   arma_extra_debug_sigprint();
00088   }
00089 
00090 
00091 
00092 template<typename eT>
00093 inline
00094 void
00095 subview_cube<eT>::operator+= (const eT val)
00096   {
00097   arma_extra_debug_sigprint();
00098   
00099   for(u32 slice = 0; slice < n_slices; ++slice)
00100     {
00101     for(u32 col = 0; col < n_cols; ++col)
00102       {
00103       eT* coldata = slice_colptr(slice,col);
00104       
00105       for(u32 row = 0; row < n_rows; ++row)
00106         {
00107         coldata[row] += val;
00108         }
00109       
00110       }
00111     }
00112 
00113   }
00114 
00115 
00116 
00117 template<typename eT>
00118 inline
00119 void
00120 subview_cube<eT>::operator-= (const eT val)
00121   {
00122   arma_extra_debug_sigprint();
00123   
00124   for(u32 slice = 0; slice < n_slices; ++slice)
00125     {
00126     for(u32 col = 0; col<n_cols; ++col)
00127       {
00128       eT* coldata = slice_colptr(slice,col);
00129       
00130       for(u32 row = 0; row<n_rows; ++row)
00131         {
00132         coldata[row] -= val;
00133         }
00134       
00135       }
00136     }
00137   }
00138 
00139 
00140 
00141 template<typename eT>
00142 inline
00143 void
00144 subview_cube<eT>::operator*= (const eT val)
00145   {
00146   arma_extra_debug_sigprint();
00147   
00148   for(u32 slice = 0; slice < n_slices; ++slice)
00149     {
00150     for(u32 col = 0; col<n_cols; ++col)
00151       {
00152       eT* coldata = slice_colptr(slice,col);
00153       
00154       for(u32 row = 0; row<n_rows; ++row)
00155         {
00156         coldata[row] *= val;
00157         }
00158       
00159       }
00160     }  
00161   }
00162 
00163 
00164 
00165 template<typename eT>
00166 inline
00167 void
00168 subview_cube<eT>::operator/= (const eT val)
00169   {
00170   arma_extra_debug_sigprint();
00171   
00172   for(u32 slice = 0; slice < n_slices; ++slice)
00173     {
00174     for(u32 col = 0; col<n_cols; ++col)
00175       {
00176       eT* coldata = slice_colptr(slice,col);
00177       
00178       for(u32 row = 0; row<n_rows; ++row)
00179         {
00180         coldata[row] /= val;
00181         }
00182       
00183       }
00184     }  
00185   }
00186 
00187 
00188 
00189 template<typename eT>
00190 template<typename T1>
00191 inline
00192 void
00193 subview_cube<eT>::operator= (const BaseCube<eT,T1>& in)
00194   {
00195   arma_extra_debug_sigprint();
00196   
00197   const unwrap_cube<T1> tmp(in.get_ref());
00198   
00199   const Cube<eT>&         x = tmp.M;
00200         subview_cube<eT>& t = *this;
00201   
00202   arma_debug_assert_same_size(t, x, "copy into subcube");
00203   
00204   
00205   for(u32 slice = 0; slice < t.n_slices; ++slice)
00206     {
00207     for(u32 col = 0; col < t.n_cols; ++col)
00208       {
00209             eT* t_coldata = t.slice_colptr(slice,col);
00210       const eT* x_coldata = x.slice_colptr(slice,col);
00211       
00212       for(u32 row = 0; row < t.n_rows; ++row)
00213         {
00214         t_coldata[row] = x_coldata[row];
00215         }
00216         
00217       }
00218     }
00219   }
00220 
00221 
00222 
00223 template<typename eT>
00224 template<typename T1>
00225 inline
00226 void
00227 subview_cube<eT>::operator+= (const BaseCube<eT,T1>& in)
00228   {
00229   arma_extra_debug_sigprint();
00230   
00231   const unwrap_cube<T1> tmp(in.get_ref());
00232   
00233   const Cube<eT>&         x = tmp.M;
00234         subview_cube<eT>& t = *this;
00235   
00236   arma_debug_assert_same_size(t, x, "cube addition");
00237   
00238   for(u32 slice = 0; slice < t.n_slices; ++slice)
00239     {
00240     for(u32 col = 0; col < t.n_cols; ++col)
00241       {
00242             eT* t_coldata = t.slice_colptr(slice,col);
00243       const eT* x_coldata = x.slice_colptr(slice,col);
00244       
00245       for(u32 row = 0; row < t.n_rows; ++row)
00246         {
00247         t_coldata[row] += x_coldata[row];
00248         }
00249       }
00250     }
00251   
00252   }
00253 
00254 
00255 
00256 template<typename eT>
00257 template<typename T1>
00258 inline
00259 void
00260 subview_cube<eT>::operator-= (const BaseCube<eT,T1>& in)
00261   {
00262   arma_extra_debug_sigprint();
00263   
00264   const unwrap_cube<T1> tmp(in.get_ref());
00265   
00266   const Cube<eT>&         x = tmp.M;
00267         subview_cube<eT>& t = *this;
00268   
00269   arma_debug_assert_same_size(t, x, "cube subtraction");
00270   
00271   
00272   for(u32 slice = 0; slice < t.n_slices; ++slice)
00273     {
00274     for(u32 col = 0; col < t.n_cols; ++col)
00275       {
00276             eT* t_coldata = t.slice_colptr(slice,col);
00277       const eT* x_coldata = x.slice_colptr(slice,col);
00278       
00279       for(u32 row = 0; row < t.n_rows; ++row)
00280         {
00281         t_coldata[row] -= x_coldata[row];
00282         }
00283       }
00284     }  
00285   }
00286 
00287 
00288 
00289 template<typename eT>
00290 template<typename T1>
00291 inline
00292 void
00293 subview_cube<eT>::operator%= (const BaseCube<eT,T1>& in)
00294   {
00295   arma_extra_debug_sigprint();
00296   
00297   const unwrap_cube<T1> tmp(in.get_ref());
00298   
00299   const Cube<eT>&         x = tmp.M;
00300         subview_cube<eT>& t = *this;
00301   
00302   arma_debug_assert_same_size(t, x, "cube schur product");
00303   
00304   for(u32 slice = 0; slice < t.n_slices; ++slice)
00305     {
00306     for(u32 col = 0; col<t.n_cols; ++col)
00307       {
00308             eT* t_coldata = t.slice_colptr(slice,col);
00309       const eT* x_coldata = x.slice_colptr(slice,col);
00310       
00311       for(u32 row = 0; row<t.n_rows; ++row)
00312         {
00313         t_coldata[row] *= x_coldata[row];
00314         }
00315       }
00316     }
00317   
00318   }
00319 
00320 
00321 
00322 template<typename eT>
00323 template<typename T1>
00324 inline
00325 void
00326 subview_cube<eT>::operator/= (const BaseCube<eT,T1>& in)
00327   {
00328   arma_extra_debug_sigprint();
00329   
00330   const unwrap_cube<T1> tmp(in.get_ref());
00331   
00332   const Cube<eT>&         x = tmp.M;
00333         subview_cube<eT>& t = *this;
00334   
00335   arma_debug_assert_same_size(t, x, "element-wise cube division");
00336   
00337   
00338   for(u32 slice = 0; slice < t.n_slices; ++slice)
00339     {
00340     for(u32 col = 0; col<t.n_cols; ++col)
00341       {
00342             eT* t_coldata = t.slice_colptr(slice,col);
00343       const eT* x_coldata = x.slice_colptr(slice,col);
00344       
00345       for(u32 row = 0; row<t.n_rows; ++row)
00346         {
00347         t_coldata[row] /= x_coldata[row];
00348         }
00349       }
00350     }
00351   
00352   }
00353 
00354 
00355 
00356 //! x.subcube(...) = y.subcube(...)
00357 template<typename eT>
00358 inline
00359 void
00360 subview_cube<eT>::operator= (const subview_cube<eT>& x_in)
00361   {
00362   arma_extra_debug_sigprint();
00363   
00364   const bool overlap = check_overlap(x_in);
00365   
00366         Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
00367   const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.aux_row2, x_in.aux_col2, x_in.aux_slice2) : 0;
00368   const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
00369   
00370   subview_cube<eT>& t = *this;
00371   
00372   arma_debug_assert_same_size(t, x, "copy into subcube");
00373   
00374   
00375   for(u32 slice = 0; slice < t.n_slices; ++slice)
00376     {
00377     for(u32 col = 0; col < t.n_cols; ++col)
00378       {
00379             eT* t_coldata = t.slice_colptr(slice,col);
00380       const eT* x_coldata = x.slice_colptr(slice,col);
00381       
00382       for(u32 row = 0; row < t.n_rows; ++row)
00383         {
00384         t_coldata[row] = x_coldata[row];
00385         }
00386       }
00387     }
00388     
00389   if(overlap)
00390     {
00391     delete tmp_subview_cube;
00392     delete tmp_cube;
00393     }
00394   
00395   }
00396 
00397 
00398 
00399 template<typename eT>
00400 inline
00401 void
00402 subview_cube<eT>::operator+= (const subview_cube<eT>& x_in)
00403   {
00404   arma_extra_debug_sigprint();
00405   
00406   const bool overlap = check_overlap(x_in);
00407   
00408         Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
00409   const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.aux_row2, x_in.aux_col2, x_in.aux_slice2) : 0;
00410   const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
00411   
00412   subview_cube<eT>& t = *this;
00413   
00414   arma_debug_assert_same_size(t, x, "cube addition");
00415   
00416   
00417   for(u32 slice = 0; slice < t.n_slices; ++slice)
00418     {
00419     for(u32 col = 0; col < t.n_cols; ++col)
00420       {
00421             eT* t_coldata = t.slice_colptr(slice,col);
00422       const eT* x_coldata = x.slice_colptr(slice,col);
00423       
00424       for(u32 row = 0; row < t.n_rows; ++row)
00425         {
00426         t_coldata[row] += x_coldata[row];
00427         }
00428       }
00429     }
00430     
00431   if(overlap)
00432     {
00433     delete tmp_subview_cube;
00434     delete tmp_cube;
00435     }
00436   
00437   }
00438 
00439 
00440 
00441 template<typename eT>
00442 inline
00443 void
00444 subview_cube<eT>::operator-= (const subview_cube<eT>& x_in)
00445   {
00446   arma_extra_debug_sigprint();
00447   
00448   const bool overlap = check_overlap(x_in);
00449   
00450         Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
00451   const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.aux_row2, x_in.aux_col2, x_in.aux_slice2) : 0;
00452   const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
00453   
00454   subview_cube<eT>& t = *this;
00455   
00456   arma_debug_assert_same_size(t, x, "cube subtraction");
00457   
00458   
00459   for(u32 slice = 0; slice < t.n_slices; ++slice)
00460     {
00461     for(u32 col = 0; col < t.n_cols; ++col)
00462       {
00463             eT* t_coldata = t.slice_colptr(slice,col);
00464       const eT* x_coldata = x.slice_colptr(slice,col);
00465       
00466       for(u32 row = 0; row < t.n_rows; ++row)
00467         {
00468         t_coldata[row] -= x_coldata[row];
00469         }
00470       }
00471     }
00472     
00473   if(overlap)
00474     {
00475     delete tmp_subview_cube;
00476     delete tmp_cube;
00477     }
00478     
00479   }
00480 
00481 
00482 
00483 template<typename eT>
00484 inline
00485 void
00486 subview_cube<eT>::operator%= (const subview_cube<eT>& x_in)
00487   {
00488   arma_extra_debug_sigprint();
00489   
00490   const bool overlap = check_overlap(x_in);
00491   
00492         Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
00493   const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.aux_row2, x_in.aux_col2, x_in.aux_slice2) : 0;
00494   const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
00495   
00496   subview_cube<eT>& t = *this;
00497   
00498   arma_debug_assert_same_size(t, x, "element-wise cube multiplication");
00499   
00500   
00501   for(u32 slice = 0; slice < t.n_slices; ++slice)
00502     {
00503     for(u32 col = 0; col < t.n_cols; ++col)
00504       {
00505             eT* t_coldata = t.slice_colptr(slice,col);
00506       const eT* x_coldata = x.slice_colptr(slice,col);
00507       
00508       for(u32 row = 0; row < t.n_rows; ++row)
00509         {
00510         t_coldata[row] *= x_coldata[row];
00511         }
00512       }
00513     }
00514     
00515   if(overlap)
00516     {
00517     delete tmp_subview_cube;
00518     delete tmp_cube;
00519     }
00520   
00521   }
00522 
00523 
00524 
00525 template<typename eT>
00526 inline
00527 void
00528 subview_cube<eT>::operator/= (const subview_cube<eT>& x_in)
00529   {
00530   arma_extra_debug_sigprint();
00531   
00532   const bool overlap = check_overlap(x_in);
00533   
00534         Cube<eT>*         tmp_cube         = overlap ? new Cube<eT>(x_in.m) : 0;
00535   const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.aux_row2, x_in.aux_col2, x_in.aux_slice2) : 0;
00536   const subview_cube<eT>& x                = overlap ? (*tmp_subview_cube) : x_in;
00537   
00538   subview_cube<eT>& t = *this;
00539   
00540   arma_debug_assert_same_size(t, x, "element-wise cube division");
00541   
00542   
00543   for(u32 slice = 0; slice < t.n_slices; ++slice)
00544     {
00545     for(u32 col = 0; col < t.n_cols; ++col)
00546       {
00547             eT* t_coldata = t.slice_colptr(slice,col);
00548       const eT* x_coldata = x.slice_colptr(slice,col);
00549       
00550       for(u32 row = 0; row < t.n_rows; ++row)
00551         {
00552         t_coldata[row] /= x_coldata[row];
00553         }
00554       }
00555     }
00556     
00557   if(overlap)
00558     {
00559     delete tmp_subview_cube;
00560     delete tmp_cube;
00561     }
00562   
00563   }
00564 
00565 
00566 
00567 template<typename eT>
00568 template<typename T1>
00569 inline
00570 void
00571 subview_cube<eT>::operator= (const Base<eT,T1>& in)
00572   {
00573   arma_extra_debug_sigprint();
00574   
00575   const unwrap<T1> tmp(in.get_ref());
00576   
00577   const Mat<eT>&          x = tmp.M;
00578         subview_cube<eT>& t = *this;
00579   
00580   arma_debug_assert_same_size(t, x, "copy into subcube");
00581   
00582   
00583   for(u32 col = 0; col < t.n_cols; ++col)
00584     {
00585           eT* t_coldata = t.slice_colptr(t.aux_slice1, col);
00586     const eT* x_coldata = x.colptr(col);
00587     
00588     for(u32 row = 0; row < t.n_rows; ++row)
00589       {
00590       t_coldata[row] = x_coldata[row];
00591       }
00592       
00593     }
00594   }
00595 
00596 
00597 
00598 template<typename eT>
00599 template<typename T1>
00600 inline
00601 void
00602 subview_cube<eT>::operator+= (const Base<eT,T1>& in)
00603   {
00604   arma_extra_debug_sigprint();
00605   
00606   const unwrap<T1> tmp(in.get_ref());
00607   
00608   const Mat<eT>&          x = tmp.M;
00609         subview_cube<eT>& t = *this;
00610   
00611   arma_debug_assert_same_size(t, x, "cube addition");
00612   
00613   for(u32 col = 0; col < t.n_cols; ++col)
00614     {
00615           eT* t_coldata = t.slice_colptr(t.aux_slice1, col);
00616     const eT* x_coldata = x.colptr(col);
00617     
00618     for(u32 row = 0; row < t.n_rows; ++row)
00619       {
00620       t_coldata[row] += x_coldata[row];
00621       }
00622     }
00623   }
00624 
00625 
00626 
00627 template<typename eT>
00628 template<typename T1>
00629 inline
00630 void
00631 subview_cube<eT>::operator-= (const Base<eT,T1>& in)
00632   {
00633   arma_extra_debug_sigprint();
00634   
00635   const unwrap<T1> tmp(in.get_ref());
00636   
00637   const Mat<eT>&          x = tmp.M;
00638         subview_cube<eT>& t = *this;
00639   
00640   arma_debug_assert_same_size(t, x, "cube subtraction");
00641   
00642   for(u32 col = 0; col < t.n_cols; ++col)
00643     {
00644           eT* t_coldata = t.slice_colptr(t.aux_slice1, col);
00645     const eT* x_coldata = x.colptr(col);
00646     
00647     for(u32 row = 0; row < t.n_rows; ++row)
00648       {
00649       t_coldata[row] -= x_coldata[row];
00650       }
00651     }
00652   }
00653 
00654 
00655 
00656 template<typename eT>
00657 template<typename T1>
00658 inline
00659 void
00660 subview_cube<eT>::operator%= (const Base<eT,T1>& in)
00661   {
00662   arma_extra_debug_sigprint();
00663   
00664   const unwrap<T1> tmp(in.get_ref());
00665   
00666   const Mat<eT>&          x = tmp.M;
00667         subview_cube<eT>& t = *this;
00668   
00669   arma_debug_assert_same_size(t, x, "cube schur product");
00670   
00671   for(u32 col = 0; col<t.n_cols; ++col)
00672     {
00673           eT* t_coldata = t.slice_colptr(t.aux_slice1, col);
00674     const eT* x_coldata = x.colptr(col);
00675     
00676     for(u32 row = 0; row<t.n_rows; ++row)
00677       {
00678       t_coldata[row] *= x_coldata[row];
00679       }
00680     }
00681   }
00682 
00683 
00684 
00685 template<typename eT>
00686 template<typename T1>
00687 inline
00688 void
00689 subview_cube<eT>::operator/= (const Base<eT,T1>& in)
00690   {
00691   arma_extra_debug_sigprint();
00692   
00693   const unwrap<T1> tmp(in.get_ref());
00694   
00695   const Mat<eT>&          x = tmp.M;
00696         subview_cube<eT>& t = *this;
00697   
00698   arma_debug_assert_same_size(t, x, "element-wise cube division");
00699   
00700   
00701   for(u32 col = 0; col<t.n_cols; ++col)
00702     {
00703           eT* t_coldata = t.slice_colptr(t.aux_slice1, col);
00704     const eT* x_coldata = x.colptr(col);
00705     
00706     for(u32 row = 0; row<t.n_rows; ++row)
00707       {
00708       t_coldata[row] /= x_coldata[row];
00709       }
00710     }
00711   }
00712 
00713 
00714 
00715 template<typename eT>
00716 inline
00717 void
00718 subview_cube<eT>::fill(const eT val)
00719   {
00720   arma_extra_debug_sigprint();
00721 
00722   for(u32 slice = 0; slice < n_slices; ++slice)
00723     {
00724     for(u32 col = 0; col < n_cols; ++col)
00725       {
00726       eT* coldata = slice_colptr(slice,col);
00727       
00728       for(u32 row = 0; row < n_rows; ++row)
00729         {
00730         coldata[row] = val;
00731         }
00732       }
00733     }
00734   
00735   }
00736 
00737 
00738 
00739 template<typename eT>
00740 inline
00741 void
00742 subview_cube<eT>::zeros()
00743   {
00744   arma_extra_debug_sigprint();
00745   
00746   fill(eT(0));
00747   }
00748 
00749 
00750 
00751 template<typename eT>
00752 inline
00753 void
00754 subview_cube<eT>::ones()
00755   {
00756   arma_extra_debug_sigprint();
00757   
00758   fill(eT(1));
00759   }
00760 
00761 
00762 
00763 template<typename eT>
00764 arma_inline
00765 eT&
00766 subview_cube<eT>::operator[](const u32 i)
00767   {
00768   arma_check( (m_ptr == 0), "subview_cube::operator[]: cube is read-only");
00769   
00770   const u32 in_slice = i / n_elem_slice;
00771   const u32 offset   = in_slice * n_elem_slice;
00772   const u32 j        = i - offset;
00773   
00774   const u32 in_col   = j / n_rows;
00775   const u32 in_row   = j % n_rows;
00776 
00777   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00778   return access::rw( (*m_ptr).mem[index] );
00779   }
00780 
00781 
00782 
00783 template<typename eT>
00784 arma_inline
00785 eT
00786 subview_cube<eT>::operator[](const u32 i) const
00787   {
00788   const u32 in_slice = i / n_elem_slice;
00789   const u32 offset   = in_slice * n_elem_slice;
00790   const u32 j        = i - offset;
00791   
00792   const u32 in_col   = j / n_rows;
00793   const u32 in_row   = j % n_rows;
00794 
00795   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00796   return m.mem[index];
00797   }
00798 
00799 
00800 
00801 template<typename eT>
00802 arma_inline
00803 eT&
00804 subview_cube<eT>::operator()(const u32 i)
00805   {
00806   arma_check( (m_ptr == 0), "subview_cube::operator(): matrix is read-only");
00807   arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
00808   
00809   const u32 in_slice = i / n_elem_slice;
00810   const u32 offset   = in_slice * n_elem_slice;
00811   const u32 j        = i - offset;
00812   
00813   const u32 in_col   = j / n_rows;
00814   const u32 in_row   = j % n_rows;
00815 
00816   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00817   return access::rw( (*m_ptr).mem[index] );
00818   }
00819 
00820 
00821 
00822 template<typename eT>
00823 arma_inline
00824 eT
00825 subview_cube<eT>::operator()(const u32 i) const
00826   {
00827   arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
00828   
00829   const u32 in_slice = i / n_elem_slice;
00830   const u32 offset   = in_slice * n_elem_slice;
00831   const u32 j        = i - offset;
00832   
00833   const u32 in_col   = j / n_rows;
00834   const u32 in_row   = j % n_rows;
00835 
00836   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00837   return m.mem[index];
00838   }
00839 
00840 
00841 
00842 template<typename eT>
00843 arma_inline
00844 eT&
00845 subview_cube<eT>::operator()(const u32 in_row, const u32 in_col, const u32 in_slice)
00846   {
00847   arma_check( (m_ptr == 0), "subview_cube::operator(): matrix is read-only");
00848   arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
00849   
00850   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00851   return access::rw( (*m_ptr).mem[index] );
00852   }
00853 
00854 
00855 
00856 template<typename eT>
00857 arma_inline
00858 eT
00859 subview_cube<eT>::operator()(const u32 in_row, const u32 in_col, const u32 in_slice) const
00860   {
00861   arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
00862   
00863   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00864   return m.mem[index];
00865   }
00866 
00867 
00868 
00869 template<typename eT>
00870 arma_inline
00871 eT&
00872 subview_cube<eT>::at(const u32 in_row, const u32 in_col, const u32 in_slice)
00873   {
00874   arma_check( (m_ptr == 0), "subview_cube::at(): cube is read-only");
00875   
00876   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00877   return access::rw( (*m_ptr).mem[index] );
00878   }
00879 
00880 
00881 
00882 template<typename eT>
00883 arma_inline
00884 eT
00885 subview_cube<eT>::at(const u32 in_row, const u32 in_col, const u32 in_slice) const
00886   {
00887   const u32 index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
00888   return m.mem[index];
00889   }
00890 
00891 
00892 
00893 template<typename eT>
00894 arma_inline
00895 eT*
00896 subview_cube<eT>::slice_colptr(const u32 in_slice, const u32 in_col)
00897   {
00898   arma_check( (m_ptr == 0), "subview_cube::slice_colptr(): cube is read-only");
00899     
00900   return & access::rw((*m_ptr).mem[  (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1  ]);
00901   }
00902 
00903 
00904 
00905 template<typename eT>
00906 arma_inline
00907 const eT*
00908 subview_cube<eT>::slice_colptr(const u32 in_slice, const u32 in_col) const
00909   {
00910   return & m.mem[ (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ];
00911   }
00912 
00913 
00914 
00915 template<typename eT>
00916 inline
00917 bool
00918 subview_cube<eT>::check_overlap(const subview_cube<eT>& x) const
00919   {
00920   const subview_cube<eT>& t = *this;
00921   
00922   if(&t.m != &x.m)
00923     {
00924     return false;
00925     }
00926   else
00927     {
00928     const bool row_overlap =
00929       (
00930       ( (x.aux_row1 >= t.aux_row1) && (x.aux_row1 <= t.aux_row2) )
00931       || 
00932       ( (x.aux_row2 >= t.aux_row1) && (x.aux_row2 <= t.aux_row2) )
00933       );
00934     
00935     const bool col_overlap =
00936       (
00937       ( (x.aux_col1 >= t.aux_col1) && (x.aux_col1 <= t.aux_col2) )
00938       || 
00939       ( (x.aux_col2 >= t.aux_col1) && (x.aux_col2 <= t.aux_col2) )
00940       );
00941     
00942     const bool slice_overlap =
00943       (
00944       ( (x.aux_slice1 >= t.aux_slice1) && (x.aux_slice1 <= t.aux_slice2) )
00945       || 
00946       ( (x.aux_slice2 >= t.aux_slice1) && (x.aux_slice2 <= t.aux_slice2) )
00947       );
00948     
00949     return (row_overlap & col_overlap & slice_overlap);
00950     }
00951   }
00952 
00953 
00954 
00955 template<typename eT>
00956 inline
00957 bool
00958 subview_cube<eT>::check_overlap(const Mat<eT>& x) const
00959   {
00960   const subview_cube<eT>& t = *this;
00961   
00962   for(u32 slice = t.aux_slice1; slice <= t.aux_slice2; ++slice)
00963     {
00964     const Mat<eT>& y = *(t.m.mat_ptrs[slice]);
00965   
00966     if( x.memptr() == y.memptr() )
00967       {
00968       return true;
00969       }
00970     }
00971   
00972   return false;
00973   }
00974 
00975 
00976 
00977 //! cube X = Y.subcube(...)
00978 template<typename eT>
00979 inline
00980 void
00981 subview_cube<eT>::extract(Cube<eT>& actual_out, const subview_cube<eT>& in)
00982   {
00983   arma_extra_debug_sigprint();
00984   
00985   //
00986   const bool alias = (&actual_out == &in.m);
00987   
00988   Cube<eT>* tmp = (alias) ? new Cube<eT> : 0;
00989   Cube<eT>& out = (alias) ? (*tmp)       : actual_out;
00990   
00991   //
00992   
00993   const u32 n_rows   = in.n_rows;
00994   const u32 n_cols   = in.n_cols;
00995   const u32 n_slices = in.n_slices;
00996   
00997   out.set_size(n_rows, n_cols, n_slices);
00998   
00999   arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    out.n_slices = %d    in.m.n_rows = %d   in.m.n_cols = %d   in.m.n_slices = %d") % out.n_rows % out.n_cols % out.n_slices % in.m.n_rows % in.m.n_cols % in.m.n_slices);
01000   
01001   
01002   for(u32 slice = 0; slice<n_slices; ++slice)
01003     {
01004     for(u32 col = 0; col<n_cols; ++col)
01005       {
01006             eT* out_coldata = out.slice_colptr(slice,col);
01007       const eT*  in_coldata =  in.slice_colptr(slice,col);
01008       
01009       for(u32 row = 0; row<n_rows; ++row)
01010         {
01011         out_coldata[row] = in_coldata[row];
01012         }
01013       
01014       }
01015     }
01016   
01017   
01018   if(alias)
01019     {
01020     actual_out = out;
01021     delete tmp;
01022     }
01023   
01024   }
01025 
01026 
01027 
01028 //! mat X = Y.subcube(...)
01029 template<typename eT>
01030 inline
01031 void
01032 subview_cube<eT>::extract(Mat<eT>& out, const subview_cube<eT>& in)
01033   {
01034   arma_extra_debug_sigprint();
01035   
01036   arma_debug_check( (in.n_slices != 1), "subview_cube::extract(): given subcube doesn't have exactly one slice" );
01037   
01038   out.set_size(in.n_rows, in.n_cols);
01039   
01040   for(u32 col = 0; col < in.n_cols; ++col)
01041     {
01042     const eT* in_coldata  = in.slice_colptr(in.aux_slice1, col);
01043           eT* out_coldata = out.colptr(col);
01044     
01045     for(u32 row = 0; row < in.n_rows; ++row)
01046       {
01047       out_coldata[row] = in_coldata[row];
01048       }
01049     }
01050   }
01051 
01052 
01053 
01054 //! cube X += Y.subcube(...)
01055 template<typename eT>
01056 inline
01057 void
01058 subview_cube<eT>::plus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
01059   {
01060   arma_extra_debug_sigprint();
01061   
01062   arma_debug_assert_same_size(out, in, "cube addition");
01063   
01064   const u32 n_rows   = out.n_rows;
01065   const u32 n_cols   = out.n_cols;
01066   const u32 n_slices = out.n_slices;
01067   
01068   for(u32 slice = 0; slice<n_slices; ++slice)
01069     {
01070     for(u32 col = 0; col<n_cols; ++col)
01071       {
01072             eT* out_coldata = out.slice_colptr(slice,col);
01073       const eT*  in_coldata =  in.slice_colptr(slice,col);
01074       
01075       for(u32 row = 0; row<n_rows; ++row)
01076         {
01077         out_coldata[row] += in_coldata[row];
01078         }
01079       }
01080     }
01081   }
01082 
01083 
01084 
01085 //! cube X -= Y.subcube(...)
01086 template<typename eT>
01087 inline
01088 void
01089 subview_cube<eT>::minus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
01090   {
01091   arma_extra_debug_sigprint();
01092   
01093   arma_debug_assert_same_size(out, in, "cube subtraction");
01094   
01095   const u32 n_rows   = out.n_rows;
01096   const u32 n_cols   = out.n_cols;
01097   const u32 n_slices = out.n_slices;
01098   
01099   for(u32 slice = 0; slice<n_slices; ++slice)
01100     {
01101     for(u32 col = 0; col<n_cols; ++col)
01102       {
01103             eT* out_coldata = out.slice_colptr(slice,col);
01104       const eT*  in_coldata =  in.slice_colptr(slice,col);
01105       
01106       for(u32 row = 0; row<n_rows; ++row)
01107         {
01108         out_coldata[row] -= in_coldata[row];
01109         }
01110       }
01111     }
01112   }
01113 
01114 
01115 
01116 //! cube X %= Y.subcube(...)
01117 template<typename eT>
01118 inline
01119 void
01120 subview_cube<eT>::schur_inplace(Cube<eT>& out, const subview_cube<eT>& in)
01121   {
01122   arma_extra_debug_sigprint();
01123   
01124   arma_debug_assert_same_size(out, in, "cube schur product");
01125   
01126   const u32 n_rows   = out.n_rows;
01127   const u32 n_cols   = out.n_cols;
01128   const u32 n_slices = out.n_slices;
01129   
01130   for(u32 slice = 0; slice<n_slices; ++slice)
01131     {
01132     for(u32 col = 0; col<n_cols; ++col)
01133       {
01134             eT* out_coldata = out.slice_colptr(slice,col);
01135       const eT*  in_coldata =  in.slice_colptr(slice,col);
01136       
01137       for(u32 row = 0; row<n_rows; ++row)
01138         {
01139         out_coldata[row] *= in_coldata[row];
01140         }
01141       }
01142     }
01143   }
01144 
01145 
01146 
01147 //! cube X /= Y.subcube(...)
01148 template<typename eT>
01149 inline
01150 void
01151 subview_cube<eT>::div_inplace(Cube<eT>& out, const subview_cube<eT>& in)
01152   {
01153   arma_extra_debug_sigprint();
01154   
01155   arma_debug_assert_same_size(out, in, "element-wise cube division");
01156   
01157   const u32 n_rows   = out.n_rows;
01158   const u32 n_cols   = out.n_cols;
01159   const u32 n_slices = out.n_slices;
01160   
01161   for(u32 slice = 0; slice<n_slices; ++slice)
01162     {
01163     for(u32 col = 0; col<n_cols; ++col)
01164       {
01165             eT* out_coldata = out.slice_colptr(slice,col);
01166       const eT*  in_coldata =  in.slice_colptr(slice,col);
01167       
01168       for(u32 row = 0; row<n_rows; ++row)
01169         {
01170         out_coldata[row] /= in_coldata[row];
01171         }
01172       }
01173     }
01174   }
01175 
01176 
01177 
01178 //! mat X += Y.subcube(...)
01179 template<typename eT>
01180 inline
01181 void
01182 subview_cube<eT>::plus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
01183   {
01184   arma_extra_debug_sigprint();
01185   
01186   arma_debug_assert_same_size(out, in, "matrix addition");
01187   
01188   for(u32 col = 0; col < in.n_cols; ++col)
01189     {
01190     const eT* in_coldata  = in.slice_colptr(in.aux_slice1, col);
01191           eT* out_coldata = out.colptr(col);
01192     
01193     for(u32 row = 0; row < in.n_rows; ++row)
01194       {
01195       out_coldata[row] += in_coldata[row];
01196       }
01197     }
01198     
01199   }
01200 
01201 
01202 
01203 //! mat X -= Y.subcube(...)
01204 template<typename eT>
01205 inline
01206 void
01207 subview_cube<eT>::minus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
01208   {
01209   arma_extra_debug_sigprint();
01210   
01211   arma_debug_assert_same_size(out, in, "matrix subtraction");
01212   
01213   for(u32 col = 0; col < in.n_cols; ++col)
01214     {
01215     const eT* in_coldata  = in.slice_colptr(in.aux_slice1, col);
01216           eT* out_coldata = out.colptr(col);
01217     
01218     for(u32 row = 0; row < in.n_rows; ++row)
01219       {
01220       out_coldata[row] -= in_coldata[row];
01221       }
01222     }
01223     
01224   }
01225 
01226 
01227 
01228 //! mat X %= Y.subcube(...)
01229 template<typename eT>
01230 inline
01231 void
01232 subview_cube<eT>::schur_inplace(Mat<eT>& out, const subview_cube<eT>& in)
01233   {
01234   arma_extra_debug_sigprint();
01235   
01236   arma_debug_assert_same_size(out, in, "matrix schur product");
01237   
01238   for(u32 col = 0; col < in.n_cols; ++col)
01239     {
01240     const eT* in_coldata  = in.slice_colptr(in.aux_slice1, col);
01241           eT* out_coldata = out.colptr(col);
01242     
01243     for(u32 row = 0; row < in.n_rows; ++row)
01244       {
01245       out_coldata[row] *= in_coldata[row];
01246       }
01247     }
01248     
01249   }
01250 
01251 
01252 
01253 //! mat X /= Y.subcube(...)
01254 template<typename eT>
01255 inline
01256 void
01257 subview_cube<eT>::div_inplace(Mat<eT>& out, const subview_cube<eT>& in)
01258   {
01259   arma_extra_debug_sigprint();
01260   
01261   arma_debug_assert_same_size(out, in, "matrix element-wise division");
01262   
01263   for(u32 col = 0; col < in.n_cols; ++col)
01264     {
01265     const eT* in_coldata  = in.slice_colptr(in.aux_slice1, col);
01266           eT* out_coldata = out.colptr(col);
01267     
01268     for(u32 row = 0; row < in.n_rows; ++row)
01269       {
01270       out_coldata[row] /= in_coldata[row];
01271       }
01272     }
01273     
01274   }
01275 
01276 
01277 
01278 //! @}