eop_cube_core_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 eop_cube_core
00018 //! @{
00019 
00020 
00021 
00022 template<typename eop_cube_type>
00023 template<typename T1>
00024 arma_hot
00025 arma_inline
00026 typename T1::elem_type
00027 eop_cube_core<eop_cube_type>::get_elem(const eOpCube<T1, eop_cube_type>& x, const u32 i)
00028   {
00029   typedef typename T1::elem_type eT;
00030   
00031   if(is_cube_generator<eop_cube_type>::value == true) { return eop_aux::generate<eT,eop_cube_type>();            }
00032   else                                                { return eop_cube_core<eop_cube_type>::process(x, x.P[i]); }
00033   }
00034 
00035 
00036 
00037 template<typename eop_cube_type>
00038 template<typename T1>
00039 arma_hot
00040 arma_inline
00041 typename T1::elem_type
00042 eop_cube_core<eop_cube_type>::get_elem(const eOpCube<T1, eop_cube_type>& x, const u32 row, const u32 col, const u32 slice)
00043   {
00044   typedef typename T1::elem_type eT;
00045   
00046   if(is_cube_generator<eop_cube_type>::value == true) { return eop_aux::generate<eT,eop_cube_type>();                           }
00047   else                                                { return eop_cube_core<eop_cube_type>::process(x, x.P.at(row,col,slice)); }
00048   }
00049 
00050 
00051 
00052 template<typename eop_cube_type>
00053 template<typename T1>
00054 arma_hot
00055 arma_inline
00056 typename T1::elem_type
00057 eop_cube_core<eop_cube_type>::process(const eOpCube<T1, eop_cube_type>& x, const typename T1::elem_type val)
00058   {
00059   typedef typename T1::elem_type eT;
00060   
00061   // the optimiser will keep only one return statement
00062   
00063        if(is_same_type<eop_cube_type, eop_cube_neg              >::value == true) { return -val;                    }
00064   else if(is_same_type<eop_cube_type, eop_cube_scalar_plus      >::value == true) { return val + x.aux;             }
00065   else if(is_same_type<eop_cube_type, eop_cube_scalar_minus_pre >::value == true) { return x.aux - val;             }
00066   else if(is_same_type<eop_cube_type, eop_cube_scalar_minus_post>::value == true) { return val - x.aux;             }
00067   else if(is_same_type<eop_cube_type, eop_cube_scalar_times     >::value == true) { return val * x.aux;             }
00068   else if(is_same_type<eop_cube_type, eop_cube_scalar_div_pre   >::value == true) { return x.aux / val;             }
00069   else if(is_same_type<eop_cube_type, eop_cube_scalar_div_post  >::value == true) { return val / x.aux;             }
00070   else if(is_same_type<eop_cube_type, eop_cube_square           >::value == true) { return val*val;                 }
00071   else if(is_same_type<eop_cube_type, eop_cube_sqrt             >::value == true) { return eop_aux::sqrt(val);      }
00072   else if(is_same_type<eop_cube_type, eop_cube_log10            >::value == true) { return eop_aux::log10(val);     }
00073   else if(is_same_type<eop_cube_type, eop_cube_log              >::value == true) { return eop_aux::log(val);       }
00074   else if(is_same_type<eop_cube_type, eop_cube_trunc_log        >::value == true) { return    arma::trunc_log(val); }
00075   else if(is_same_type<eop_cube_type, eop_cube_exp              >::value == true) { return eop_aux::exp(val);       }
00076   else if(is_same_type<eop_cube_type, eop_cube_trunc_exp        >::value == true) { return    arma::trunc_exp(val); }
00077   else if(is_same_type<eop_cube_type, eop_cube_cos              >::value == true) { return eop_aux::cos(val);       }
00078   else if(is_same_type<eop_cube_type, eop_cube_cosh             >::value == true) { return eop_aux::cosh(val);      }
00079   else if(is_same_type<eop_cube_type, eop_cube_acos             >::value == true) { return eop_aux::acos(val);      }
00080   else if(is_same_type<eop_cube_type, eop_cube_acosh            >::value == true) { return eop_aux::acosh(val);     }
00081   else if(is_same_type<eop_cube_type, eop_cube_sin              >::value == true) { return eop_aux::sin(val);       }
00082   else if(is_same_type<eop_cube_type, eop_cube_sinh             >::value == true) { return eop_aux::sinh(val);      }
00083   else if(is_same_type<eop_cube_type, eop_cube_asin             >::value == true) { return eop_aux::asin(val);      }
00084   else if(is_same_type<eop_cube_type, eop_cube_asinh            >::value == true) { return eop_aux::asinh(val);     }
00085   else if(is_same_type<eop_cube_type, eop_cube_tan              >::value == true) { return eop_aux::tan(val);       }
00086   else if(is_same_type<eop_cube_type, eop_cube_tanh             >::value == true) { return eop_aux::tanh(val);      }
00087   else if(is_same_type<eop_cube_type, eop_cube_atan             >::value == true) { return eop_aux::atan(val);      }
00088   else if(is_same_type<eop_cube_type, eop_cube_atanh            >::value == true) { return eop_aux::atanh(val);     }
00089   else if(is_same_type<eop_cube_type, eop_cube_eps              >::value == true) { return eop_aux::direct_eps(val);}
00090   else if(is_same_type<eop_cube_type, eop_cube_abs              >::value == true) { return eop_aux::arma_abs(val);  }
00091   else if(is_same_type<eop_cube_type, eop_cube_conj             >::value == true) { return eop_aux::conj(val);      }
00092   else if(is_same_type<eop_cube_type, eop_cube_pow              >::value == true) { return eop_aux::pow(val, x.aux);}
00093   else if(is_same_type<eop_cube_type, eop_cube_pow_int          >::value == true)
00094     {
00095     const int exponent = (x.aux_u32_b == 0) ? int(x.aux_u32_a) : -int(x.aux_u32_a);
00096     
00097     return eop_aux::pow_int(val, exponent);
00098     }
00099   else
00100     {
00101     arma_stop("eop_cube_core::process(): unhandled eop_cube_type");
00102     return eT(0);
00103     }
00104   }
00105 
00106 
00107 
00108 template<typename eop_cube_type>
00109 template<typename T1>
00110 arma_hot
00111 inline
00112 void
00113 eop_cube_core<eop_cube_type>::apply(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00114   {
00115   arma_extra_debug_sigprint();
00116   
00117   if(is_Cube<T1>::value == true)
00118     {
00119     eop_cube_core<eop_cube_type>::apply_unwrap(out, x);
00120     }
00121   else
00122     {
00123     eop_cube_core<eop_cube_type>::apply_proxy(out, x);
00124     }
00125   }
00126 
00127 
00128 
00129 template<typename eop_cube_type>
00130 template<typename T1>
00131 arma_hot
00132 inline
00133 void
00134 eop_cube_core<eop_cube_type>::apply_proxy(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00135   {
00136   arma_extra_debug_sigprint();
00137   
00138   // eop_cube_type::apply() function is not allowed to unwrap things
00139   // (in order to get the input into a common format).
00140   // the proxy class is already providing objects with element access
00141   
00142   typedef typename T1::elem_type eT;
00143   
00144   const ProxyCube<T1>& P = x.P;
00145   
00146   out.set_size(P.n_rows, P.n_cols, P.n_slices);
00147   
00148         eT* out_mem = out.memptr();
00149   const u32 n_elem  = P.n_elem;
00150   
00151   if(is_cube_generator<eop_cube_type>::value == true)
00152     {
00153     for(u32 i=0; i<n_elem; ++i)
00154       {
00155       out_mem[i] = eop_aux::generate<eT,eop_cube_type>();
00156       }
00157     }
00158   else
00159     {
00160     for(u32 i=0; i<n_elem; ++i)
00161       {
00162       out_mem[i] = eop_cube_core<eop_cube_type>::process(x, P[i]);
00163       }
00164     }
00165   }
00166 
00167 
00168 
00169 template<typename eop_cube_type>
00170 template<typename T1>
00171 arma_hot
00172 inline
00173 void
00174 eop_cube_core<eop_cube_type>::apply_unwrap(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00175   {
00176   arma_extra_debug_sigprint();
00177   
00178   typedef typename T1::elem_type eT;
00179   
00180   const ProxyCube<T1>& P = x.P;
00181   
00182   out.set_size(P.n_rows, P.n_cols, P.n_slices);
00183   
00184         eT* out_mem = out.memptr();
00185   const u32 n_elem  = P.n_elem;
00186   
00187   if(is_cube_generator<eop_cube_type>::value == true)
00188     {
00189     for(u32 i=0; i<n_elem; ++i)
00190       {
00191       out_mem[i] = eop_aux::generate<eT,eop_cube_type>();
00192       }
00193     }
00194   else
00195     {
00196     const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);
00197     
00198     const Cube<eT>& A     = tmp.M;
00199     const eT*       A_mem = A.memptr();
00200     
00201     for(u32 i=0; i<n_elem; ++i)
00202       {
00203       out_mem[i] = eop_cube_core<eop_cube_type>::process(x, A_mem[i]);
00204       }
00205     }
00206   }
00207 
00208 
00209 
00210 template<typename eop_cube_type>
00211 template<typename T1>
00212 arma_hot
00213 inline
00214 void
00215 eop_cube_core<eop_cube_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00216   {
00217   arma_extra_debug_sigprint();
00218   
00219   typedef typename T1::elem_type eT;
00220   
00221   const ProxyCube<T1>& P = x.P;
00222   
00223   arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "cube addition");
00224   
00225         eT* out_mem = out.memptr();
00226   const u32 n_elem  = P.n_elem;
00227   
00228   if(is_cube_generator<eop_cube_type>::value == true)
00229     {
00230     for(u32 i=0; i<n_elem; ++i)
00231       {
00232       out_mem[i] += eop_aux::generate<eT,eop_cube_type>();
00233       }
00234     }
00235   else
00236     {
00237     for(u32 i=0; i<n_elem; ++i)
00238       {
00239       out_mem[i] += eop_cube_core<eop_cube_type>::process(x, P[i]);
00240       }
00241     }
00242   }
00243 
00244 
00245 
00246 template<typename eop_cube_type>
00247 template<typename T1>
00248 arma_hot
00249 inline
00250 void
00251 eop_cube_core<eop_cube_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00252   {
00253   arma_extra_debug_sigprint();
00254   
00255   typedef typename T1::elem_type eT;
00256   
00257   const ProxyCube<T1>& P = x.P;
00258   
00259   arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "cube subtraction");
00260   
00261         eT* out_mem = out.memptr();
00262   const u32 n_elem  = P.n_elem;
00263   
00264   if(is_cube_generator<eop_cube_type>::value == true)
00265     {
00266     for(u32 i=0; i<n_elem; ++i)
00267       {
00268       out_mem[i] -= eop_aux::generate<eT,eop_cube_type>();
00269       }
00270     }
00271   else
00272     {
00273     for(u32 i=0; i<n_elem; ++i)
00274       {
00275       out_mem[i] -= eop_cube_core<eop_cube_type>::process(x, P[i]);
00276       }
00277     }
00278   }
00279 
00280 
00281 
00282 template<typename eop_cube_type>
00283 template<typename T1>
00284 arma_hot
00285 inline
00286 void
00287 eop_cube_core<eop_cube_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00288   {
00289   arma_extra_debug_sigprint();
00290   
00291   typedef typename T1::elem_type eT;
00292   
00293   const ProxyCube<T1>& P = x.P;
00294   
00295   arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "element-wise cube multiplication");
00296   
00297         eT* out_mem = out.memptr();
00298   const u32 n_elem  = P.n_elem;
00299   
00300   if(is_cube_generator<eop_cube_type>::value == true)
00301     {
00302     for(u32 i=0; i<n_elem; ++i)
00303       {
00304       out_mem[i] *= eop_aux::generate<eT,eop_cube_type>();
00305       }
00306     }
00307   else
00308     {
00309     for(u32 i=0; i<n_elem; ++i)
00310       {
00311       out_mem[i] *= eop_cube_core<eop_cube_type>::process(x, P[i]);
00312       }
00313     }
00314   }
00315 
00316 
00317 
00318 template<typename eop_cube_type>
00319 template<typename T1>
00320 arma_hot
00321 inline
00322 void
00323 eop_cube_core<eop_cube_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00324   {
00325   arma_extra_debug_sigprint();
00326   
00327   typedef typename T1::elem_type eT;
00328   
00329   const ProxyCube<T1>& P = x.P;
00330   
00331   arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "element-wise cube division");
00332   
00333         eT* out_mem = out.memptr();
00334   const u32 n_elem  = P.n_elem;
00335   
00336   if(is_cube_generator<eop_cube_type>::value == true)
00337     {
00338     for(u32 i=0; i<n_elem; ++i)
00339       {
00340       out_mem[i] /= eop_aux::generate<eT,eop_cube_type>();
00341       }
00342     }
00343   else
00344     {
00345     for(u32 i=0; i<n_elem; ++i)
00346       {
00347       out_mem[i] /= eop_cube_core<eop_cube_type>::process(x, P[i]);
00348       }
00349     }
00350   }
00351 
00352 
00353 
00354 //! @}