subview_field_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_field
00018 //! @{
00019 
00020 
00021 template<typename oT>
00022 inline
00023 subview_field<oT>::~subview_field()
00024   {
00025   arma_extra_debug_sigprint();
00026   }
00027 
00028 
00029 
00030 template<typename oT>
00031 arma_inline
00032 subview_field<oT>::subview_field
00033   (
00034   const field<oT>& in_f,
00035   const u32        in_row1,
00036   const u32        in_col1,
00037   const u32        in_row2,
00038   const u32        in_col2
00039   )
00040   : f(in_f)
00041   , f_ptr(0)
00042   , aux_row1(in_row1)
00043   , aux_col1(in_col1)
00044   , aux_row2(in_row2)
00045   , aux_col2(in_col2)
00046   , n_rows(1 + in_row2 - in_row1)
00047   , n_cols(1 + in_col2 - in_col1)
00048   , n_elem(n_rows*n_cols)
00049   {
00050   arma_extra_debug_sigprint();
00051   }
00052 
00053 
00054 
00055 template<typename oT>
00056 arma_inline
00057 subview_field<oT>::subview_field
00058   (
00059         field<oT>& in_f,
00060   const u32        in_row1,
00061   const u32        in_col1,
00062   const u32        in_row2,
00063   const u32        in_col2
00064   )
00065   : f(in_f)
00066   , f_ptr(&in_f)
00067   , aux_row1(in_row1)
00068   , aux_col1(in_col1)
00069   , aux_row2(in_row2)
00070   , aux_col2(in_col2)
00071   , n_rows(1 + in_row2 - in_row1)
00072   , n_cols(1 + in_col2 - in_col1)
00073   , n_elem(n_rows*n_cols)
00074   {
00075   arma_extra_debug_sigprint();
00076   }
00077 
00078 
00079 
00080 template<typename oT>
00081 inline
00082 void
00083 subview_field<oT>::operator= (const field<oT>& x)
00084   {
00085   arma_extra_debug_sigprint();
00086   
00087   subview_field<oT>& t = *this;
00088   
00089   arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols), "incompatible field dimensions");
00090   
00091   for(u32 col=0; col<t.n_cols; ++col)
00092     {
00093     for(u32 row=0; row<t.n_rows; ++row)
00094       {
00095       t.at(row,col) = x.at(row,col);
00096       }
00097     }
00098   }
00099 
00100 
00101 
00102 //! x.subfield(...) = y.subfield(...)
00103 template<typename oT>
00104 inline
00105 void
00106 subview_field<oT>::operator= (const subview_field<oT>& x_in)
00107   {
00108   arma_extra_debug_sigprint();
00109   
00110   const bool overlap = check_overlap(x_in);
00111         
00112         field<oT>*         tmp_field   = overlap ? new field<oT>(x_in.f) : 0;
00113   const subview_field<oT>* tmp_subview = overlap ? new subview_field<oT>(*tmp_field, x_in.aux_row1, x_in.aux_col1, x_in.aux_row2, x_in.aux_col2) : 0;
00114   const subview_field<oT>& x           = overlap ? (*tmp_subview) : x_in;
00115   
00116   subview_field<oT>& t = *this;
00117   
00118   arma_debug_check( (t.n_rows != x.n_rows) || (t.n_cols != x.n_cols), "incompatible field dimensions");
00119   
00120   for(u32 col=0; col<t.n_cols; ++col)
00121     {
00122     for(u32 row=0; row<t.n_rows; ++row)
00123       {
00124       t.at(row,col) = x.at(row,col);
00125       }
00126     }
00127     
00128   if(overlap)
00129     {
00130     delete tmp_subview;
00131     delete tmp_field;
00132     }
00133   }
00134 
00135 
00136 
00137 template<typename oT>
00138 arma_inline
00139 oT&
00140 subview_field<oT>::operator[](const u32 i)
00141   {
00142   arma_check( (f_ptr == 0), "subview_field::operator[]: field is read-only");
00143   
00144   const u32 in_col = i / n_rows;
00145   const u32 in_row = i % n_rows;
00146     
00147   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00148   
00149   return *((*f_ptr).mem[index]);
00150   }
00151 
00152 
00153 
00154 template<typename oT>
00155 arma_inline
00156 const oT&
00157 subview_field<oT>::operator[](const u32 i) const
00158   {
00159   const u32 in_col = i / n_rows;
00160   const u32 in_row = i % n_rows;
00161   
00162   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00163   
00164   return *(f.mem[index]);
00165   }
00166 
00167 
00168 
00169 template<typename oT>
00170 arma_inline
00171 oT&
00172 subview_field<oT>::operator()(const u32 i)
00173   {
00174   arma_check( (f_ptr == 0), "subview_field::operator(): field is read-only");
00175   arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds");
00176     
00177   const u32 in_col = i / n_rows;
00178   const u32 in_row = i % n_rows;
00179   
00180   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00181   
00182   return *((*f_ptr).mem[index]);
00183   }
00184 
00185 
00186 
00187 template<typename oT>
00188 arma_inline
00189 const oT&
00190 subview_field<oT>::operator()(const u32 i) const
00191   {
00192   arma_debug_check( (i >= n_elem), "subview_field::operator(): index out of bounds");
00193   
00194   const u32 in_col = i / n_rows;
00195   const u32 in_row = i % n_rows;
00196   
00197   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00198   
00199   return *(f.mem[index]);
00200   }
00201 
00202 
00203 
00204 template<typename oT>
00205 arma_inline
00206 oT&
00207 subview_field<oT>::operator()(const u32 in_row, const u32 in_col)
00208   {
00209   arma_check( (f_ptr == 0), "subview_field::operator(): field is read-only");
00210   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview_field::operator(): index out of bounds");
00211   
00212   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00213   
00214   return *((*f_ptr).mem[index]);
00215   }
00216 
00217 
00218 
00219 template<typename oT>
00220 arma_inline
00221 const oT&
00222 subview_field<oT>::operator()(const u32 in_row, const u32 in_col) const
00223   {
00224   arma_debug_check( ((in_row >= n_rows) || (in_col >= n_cols)), "subview_field::operator(): index out of bounds");
00225   
00226   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00227   
00228   return *(f.mem[index]);
00229   }
00230 
00231 
00232 
00233 template<typename oT>
00234 arma_inline
00235 oT&
00236 subview_field<oT>::at(const u32 in_row, const u32 in_col)
00237   {
00238   //arma_extra_debug_sigprint();
00239   
00240   arma_check( (f_ptr == 0), "subview_field::at(): field is read-only");
00241   
00242   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00243   
00244   return *((*f_ptr).mem[index]);
00245   }
00246 
00247 
00248 
00249 template<typename oT>
00250 arma_inline
00251 const oT&
00252 subview_field<oT>::at(const u32 in_row, const u32 in_col) const
00253   {
00254   //arma_extra_debug_sigprint();
00255   
00256   const u32 index = (in_col + aux_col1)*f.n_rows + aux_row1 + in_row;
00257   
00258   return *(f.mem[index]);
00259   }
00260 
00261 
00262 
00263 template<typename oT>
00264 inline
00265 bool
00266 subview_field<oT>::check_overlap(const subview_field<oT>& x) const
00267   {
00268   const subview_field<oT>& t = *this;
00269   
00270   if(&t.f != &x.f)
00271     {
00272     return false;
00273     }
00274   else
00275     {
00276     const bool row_overlap =
00277       (
00278       ( (x.aux_row1 >= t.aux_row1) && (x.aux_row1 <= t.aux_row2) )
00279       || 
00280       ( (x.aux_row2 >= t.aux_row1) && (x.aux_row2 <= t.aux_row2) )
00281       );
00282     
00283     const bool col_overlap =
00284       (
00285       ( (x.aux_col1 >= t.aux_col1) && (x.aux_col1 <= t.aux_col2) )
00286       || 
00287       ( (x.aux_col2 >= t.aux_col1) && (x.aux_col2 <= t.aux_col2) )
00288       );
00289     
00290     
00291     return (row_overlap & col_overlap);
00292     }
00293   }
00294 
00295 
00296 
00297 //! X = Y.subfield(...)
00298 template<typename oT>
00299 inline
00300 void
00301 subview_field<oT>::extract(field<oT>& actual_out, const subview_field<oT>& in)
00302   {
00303   arma_extra_debug_sigprint();
00304   
00305   //
00306   const bool alias = (&actual_out == &in.f);
00307   
00308   field<oT>* tmp = (alias) ? new field<oT> : 0;
00309   field<oT>& out = (alias) ? (*tmp)        : actual_out;
00310   
00311   //
00312   
00313   const u32 n_rows = in.n_rows;
00314   const u32 n_cols = in.n_cols;
00315   
00316   out.set_size(n_rows, n_cols);
00317   
00318   arma_extra_debug_print(arma_boost::format("out.n_rows = %d   out.n_cols = %d    in.m.n_rows = %d  in.m.n_cols = %d") % out.n_rows % out.n_cols % in.f.n_rows % in.f.n_cols );
00319   
00320   for(u32 col = 0; col<n_cols; ++col)
00321     {
00322     for(u32 row = 0; row<n_rows; ++row)
00323       {
00324       out.at(row,col) = in.at(row,col);
00325       }
00326     }
00327   
00328   
00329   if(alias)
00330     {
00331     actual_out = out;
00332     delete tmp;
00333     }
00334   
00335   }
00336 
00337 
00338 
00339 //! @}