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