subview_field_meat.hpp

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