eglue_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 eglue_cube_core
00018 //! @{
00019 
00020 
00021 
00022 template<typename eglue_type>
00023 template<typename T1, typename T2>
00024 arma_inline
00025 typename T1::elem_type
00026 eglue_cube_core<eglue_type>::get_elem(const eGlueCube<T1, T2, eglue_type>& x, const u32 i)
00027   {
00028   typedef typename T1::elem_type eT;
00029   
00030   // the optimiser will keep only one return statement
00031   
00032        if(is_same_type<eglue_type, eglue_cube_plus >::value == true) { return x.P1[i] + x.P2[i]; }
00033   else if(is_same_type<eglue_type, eglue_cube_minus>::value == true) { return x.P1[i] - x.P2[i]; }
00034   else if(is_same_type<eglue_type, eglue_cube_div  >::value == true) { return x.P1[i] / x.P2[i]; }
00035   else if(is_same_type<eglue_type, eglue_cube_schur>::value == true) { return x.P1[i] * x.P2[i]; }
00036   else
00037     {
00038     arma_stop("eglue_cube_core::get_elem(): unhandled eglue_type");
00039     return eT(0);
00040     }
00041   }
00042 
00043 
00044 
00045 template<typename eglue_type>
00046 template<typename T1, typename T2>
00047 arma_inline
00048 typename T1::elem_type
00049 eglue_cube_core<eglue_type>::get_elem(const eGlueCube<T1, T2, eglue_type>& x, const u32 row, const u32 col, const u32 slice)
00050   {
00051   typedef typename T1::elem_type eT;
00052   
00053        if(is_same_type<eglue_type, eglue_cube_plus >::value == true) { return x.P1.at(row,col,slice) + x.P2.at(row,col,slice); }
00054   else if(is_same_type<eglue_type, eglue_cube_minus>::value == true) { return x.P1.at(row,col,slice) - x.P2.at(row,col,slice); }
00055   else if(is_same_type<eglue_type, eglue_cube_div  >::value == true) { return x.P1.at(row,col,slice) / x.P2.at(row,col,slice); }
00056   else if(is_same_type<eglue_type, eglue_cube_schur>::value == true) { return x.P1.at(row,col,slice) * x.P2.at(row,col,slice); }
00057   else
00058     {
00059     arma_stop("eglue_cube_core::get_elem(): unhandled eglue_type");
00060     return eT(0);
00061     }
00062   }
00063 
00064 
00065 
00066 template<typename eglue_type>
00067 template<typename T1, typename T2>
00068 arma_hot
00069 inline
00070 void
00071 eglue_cube_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
00072   {
00073   arma_extra_debug_sigprint();
00074   
00075   // eglue_type::apply() function is not allowed to unwrap things
00076   // (in order to get the input into a common format).
00077   // the proxy class is already providing objects with element access
00078   
00079   typedef typename T1::elem_type eT;
00080   
00081   const ProxyCube<T1>& P1 = x.P1;
00082   const ProxyCube<T2>& P2 = x.P2;
00083   
00084   out.set_size(P1.n_rows, P1.n_cols, P1.n_slices);
00085   
00086         eT* out_mem = out.memptr();
00087   const u32 n_elem  = P1.n_elem;
00088   
00089        if(is_same_type<eglue_type, eglue_cube_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] + P2[i]; }
00090   else if(is_same_type<eglue_type, eglue_cube_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] - P2[i]; }
00091   else if(is_same_type<eglue_type, eglue_cube_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] / P2[i]; }
00092   else if(is_same_type<eglue_type, eglue_cube_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] * P2[i]; }
00093   else
00094     {
00095     arma_stop("eglue_cube_core::apply(): unhandled eglue_type");
00096     }
00097   }
00098 
00099 
00100 
00101 template<typename eglue_type>
00102 template<typename T1, typename T2>
00103 arma_hot
00104 inline
00105 void
00106 eglue_cube_core<eglue_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
00107   {
00108   arma_extra_debug_sigprint();
00109   
00110   typedef typename T1::elem_type eT;
00111   
00112   const ProxyCube<T1>& P1 = x.P1;
00113   const ProxyCube<T2>& P2 = x.P2;
00114   
00115   arma_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P1.n_rows, P1.n_cols, P1.n_slices, "cube addition");
00116   
00117         eT* out_mem = out.memptr();
00118   const u32 n_elem  = P1.n_elem;
00119   
00120        if(is_same_type<eglue_type, eglue_cube_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] += P1[i] + P2[i]; }
00121   else if(is_same_type<eglue_type, eglue_cube_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] += P1[i] - P2[i]; }
00122   else if(is_same_type<eglue_type, eglue_cube_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] += P1[i] / P2[i]; }
00123   else if(is_same_type<eglue_type, eglue_cube_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] += P1[i] * P2[i]; }
00124   else
00125     {
00126     arma_stop("eglue_cube_core::apply_inplace_plus(): unhandled eglue_type");
00127     }
00128   }
00129 
00130 
00131 
00132 template<typename eglue_type>
00133 template<typename T1, typename T2>
00134 arma_hot
00135 inline
00136 void
00137 eglue_cube_core<eglue_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
00138   {
00139   arma_extra_debug_sigprint();
00140   
00141   typedef typename T1::elem_type eT;
00142   
00143   const ProxyCube<T1>& P1 = x.P1;
00144   const ProxyCube<T2>& P2 = x.P2;
00145   
00146   arma_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P1.n_rows, P1.n_cols, P1.n_slices, "cube subtraction");
00147   
00148         eT* out_mem = out.memptr();
00149   const u32 n_elem  = P1.n_elem;
00150   
00151        if(is_same_type<eglue_type, eglue_cube_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] -= P1[i] + P2[i]; }
00152   else if(is_same_type<eglue_type, eglue_cube_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] -= P1[i] - P2[i]; }
00153   else if(is_same_type<eglue_type, eglue_cube_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] -= P1[i] / P2[i]; }
00154   else if(is_same_type<eglue_type, eglue_cube_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] -= P1[i] * P2[i]; }
00155   else 
00156     {
00157     arma_stop("eglue_cube_core::apply_inplace_minus(): unhandled eglue_type");
00158     }
00159   }
00160 
00161 
00162 
00163 template<typename eglue_type>
00164 template<typename T1, typename T2>
00165 arma_hot
00166 inline
00167 void
00168 eglue_cube_core<eglue_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
00169   {
00170   arma_extra_debug_sigprint();
00171   
00172   typedef typename T1::elem_type eT;
00173   
00174   const ProxyCube<T1>& P1 = x.P1;
00175   const ProxyCube<T2>& P2 = x.P2;
00176   
00177   arma_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P1.n_rows, P1.n_cols, P1.n_slices, "element-wise cube multiplication");
00178   
00179         eT* out_mem = out.memptr();
00180   const u32 n_elem  = P1.n_elem;
00181   
00182        if(is_same_type<eglue_type, eglue_cube_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] + P2[i]; }
00183   else if(is_same_type<eglue_type, eglue_cube_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] - P2[i]; }
00184   else if(is_same_type<eglue_type, eglue_cube_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] / P2[i]; }
00185   else if(is_same_type<eglue_type, eglue_cube_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] * P2[i]; }
00186   else
00187     {
00188     arma_stop("eglue_cube_core::apply_inplace_schur(): unhandled eglue_type");
00189     }
00190   }
00191 
00192 
00193 
00194 template<typename eglue_type>
00195 template<typename T1, typename T2>
00196 arma_hot
00197 inline
00198 void
00199 eglue_cube_core<eglue_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eGlueCube<T1, T2, eglue_type>& x)
00200   {
00201   arma_extra_debug_sigprint();
00202   
00203   typedef typename T1::elem_type eT;
00204   
00205   const ProxyCube<T1>& P1 = x.P1;
00206   const ProxyCube<T2>& P2 = x.P2;
00207   
00208   arma_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P1.n_rows, P1.n_cols, P1.n_slices, "element-wise cube division");
00209   
00210         eT* out_mem = out.memptr();
00211   const u32 n_elem  = P1.n_elem;
00212   
00213        if(is_same_type<eglue_type, eglue_cube_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] + P2[i]; }
00214   else if(is_same_type<eglue_type, eglue_cube_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] - P2[i]; }
00215   else if(is_same_type<eglue_type, eglue_cube_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] / P2[i]; }
00216   else if(is_same_type<eglue_type, eglue_cube_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] * P2[i]; }
00217   else
00218     {
00219     arma_stop("eglue_cube_core::apply_inplace_div(): unhandled eglue_type");
00220     }
00221   }
00222 
00223 
00224 
00225 //! @}