eglue_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_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_core<eglue_type>::get_elem(const eGlue<T1, T2, eglue_type>& x, const u32 i)
00027   {
00028   // arma_extra_debug_sigprint();
00029   
00030   typedef typename T1::elem_type eT;
00031   
00032   // the optimiser will keep only one return statement
00033   
00034        if(is_same_type<eglue_type, eglue_plus >::value == true) { return x.P1[i] + x.P2[i]; }
00035   else if(is_same_type<eglue_type, eglue_minus>::value == true) { return x.P1[i] - x.P2[i]; }
00036   else if(is_same_type<eglue_type, eglue_div  >::value == true) { return x.P1[i] / x.P2[i]; }
00037   else if(is_same_type<eglue_type, eglue_schur>::value == true) { return x.P1[i] * x.P2[i]; }
00038   else
00039     {
00040     arma_stop("eglue_core::get_elem(): unhandled eglue_type");
00041     return eT(0);
00042     }
00043   }
00044 
00045 
00046 
00047 template<typename eglue_type>
00048 template<typename T1, typename T2>
00049 arma_inline
00050 typename T1::elem_type
00051 eglue_core<eglue_type>::get_elem(const eGlue<T1, T2, eglue_type>& x, const u32 row, const u32 col)
00052   {
00053   // arma_extra_debug_sigprint();
00054   
00055   typedef typename T1::elem_type eT;
00056   
00057        if(is_same_type<eglue_type, eglue_plus >::value == true) { return x.P1.at(row,col) + x.P2.at(row,col); }
00058   else if(is_same_type<eglue_type, eglue_minus>::value == true) { return x.P1.at(row,col) - x.P2.at(row,col); }
00059   else if(is_same_type<eglue_type, eglue_div  >::value == true) { return x.P1.at(row,col) / x.P2.at(row,col); }
00060   else if(is_same_type<eglue_type, eglue_schur>::value == true) { return x.P1.at(row,col) * x.P2.at(row,col); }
00061   else
00062     {
00063     arma_stop("eglue_core::get_elem(): unhandled eglue_type");
00064     return eT(0);
00065     }
00066   }
00067 
00068 
00069 
00070 template<typename eglue_type>
00071 template<typename T1, typename T2>
00072 arma_inline
00073 void
00074 eglue_core<eglue_type>::apply(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
00075   {
00076   arma_extra_debug_sigprint();
00077   
00078   if( (is_Mat<T1>::value == true) && (is_Mat<T2>::value == true) )
00079     {
00080     eglue_core<eglue_type>::apply_unwrap(out, x);
00081     }
00082   else
00083     {
00084     eglue_core<eglue_type>::apply_proxy(out, x);
00085     }
00086   }
00087 
00088 
00089 
00090 template<typename eglue_type>
00091 template<typename T1, typename T2>
00092 arma_hot
00093 inline
00094 void
00095 eglue_core<eglue_type>::apply_proxy(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
00096   {
00097   arma_extra_debug_sigprint();
00098   
00099   // eglue_type::apply_proxy() function is not allowed to unwrap things
00100   // (in order to get the input into a common format).
00101   // the proxy class is already providing objects with element access
00102   
00103   typedef typename T1::elem_type eT;
00104   
00105   const Proxy<T1>& P1 = x.P1;
00106   const Proxy<T2>& P2 = x.P2;
00107   
00108   out.set_size(P1.n_rows, P1.n_cols);
00109   
00110         eT* out_mem = out.memptr();
00111   const u32 n_elem  = P1.n_elem;
00112   
00113        if(is_same_type<eglue_type, eglue_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] + P2[i]; }
00114   else if(is_same_type<eglue_type, eglue_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] - P2[i]; }
00115   else if(is_same_type<eglue_type, eglue_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] / P2[i]; }
00116   else if(is_same_type<eglue_type, eglue_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = P1[i] * P2[i]; }
00117   else
00118     {
00119     arma_stop("eglue_core::apply_proxy(): unhandled eglue_type");
00120     }
00121   }
00122 
00123 
00124 
00125 template<typename eglue_type>
00126 template<typename T1, typename T2>
00127 arma_hot
00128 inline
00129 void
00130 eglue_core<eglue_type>::apply_unwrap(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
00131   {
00132   arma_extra_debug_sigprint();
00133   
00134   typedef typename T1::elem_type eT;
00135   
00136   const unwrap<typename Proxy<T1>::stored_type> tmp1(x.P1.Q);
00137   const unwrap<typename Proxy<T2>::stored_type> tmp2(x.P2.Q);
00138   
00139   const Mat<eT>& A = tmp1.M;
00140   const Mat<eT>& B = tmp2.M;
00141   
00142   out.set_size(A.n_rows, A.n_cols);
00143   
00144         eT* out_mem = out.memptr();
00145   const eT* A_mem   = A.memptr();
00146   const eT* B_mem   = B.memptr();
00147   const u32 n_elem  = A.n_elem;
00148   
00149        if(is_same_type<eglue_type, eglue_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = A_mem[i] + B_mem[i]; }
00150   else if(is_same_type<eglue_type, eglue_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = A_mem[i] - B_mem[i]; }
00151   else if(is_same_type<eglue_type, eglue_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = A_mem[i] / B_mem[i]; }
00152   else if(is_same_type<eglue_type, eglue_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] = A_mem[i] * B_mem[i]; }
00153   else
00154     {
00155     arma_stop("eglue_core::apply_unwrap(): unhandled eglue_type");
00156     }
00157   }
00158 
00159 
00160 
00161 template<typename eglue_type>
00162 template<typename T1, typename T2>
00163 arma_hot
00164 inline
00165 void
00166 eglue_core<eglue_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
00167   {
00168   arma_extra_debug_sigprint();
00169   
00170   typedef typename T1::elem_type eT;
00171   
00172   const Proxy<T1>& P1 = x.P1;
00173   const Proxy<T2>& P2 = x.P2;
00174   
00175   arma_assert_same_size(out.n_rows, out.n_cols, P1.n_rows, P1.n_cols, "matrix addition");
00176   
00177         eT* out_mem = out.memptr();
00178   const u32 n_elem  = P1.n_elem;
00179   
00180        if(is_same_type<eglue_type, eglue_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] += P1[i] + P2[i]; }
00181   else if(is_same_type<eglue_type, eglue_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] += P1[i] - P2[i]; }
00182   else if(is_same_type<eglue_type, eglue_div  >::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_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] += P1[i] * P2[i]; }
00184   else
00185     {
00186     arma_stop("eglue_core::apply_inplace_plus(): unhandled eglue_type");
00187     }
00188   }
00189 
00190 
00191 
00192 template<typename eglue_type>
00193 template<typename T1, typename T2>
00194 arma_hot
00195 inline
00196 void
00197 eglue_core<eglue_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
00198   {
00199   arma_extra_debug_sigprint();
00200   
00201   typedef typename T1::elem_type eT;
00202   
00203   const Proxy<T1>& P1 = x.P1;
00204   const Proxy<T2>& P2 = x.P2;
00205   
00206   arma_assert_same_size(out.n_rows, out.n_cols, P1.n_rows, P1.n_cols, "matrix subtraction");
00207   
00208         eT* out_mem = out.memptr();
00209   const u32 n_elem  = P1.n_elem;
00210   
00211        if(is_same_type<eglue_type, eglue_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] -= P1[i] + P2[i]; }
00212   else if(is_same_type<eglue_type, eglue_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] -= P1[i] - P2[i]; }
00213   else if(is_same_type<eglue_type, eglue_div  >::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_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] -= P1[i] * P2[i]; }
00215   else 
00216     {
00217     arma_stop("eglue_core::apply_inplace_minus(): unhandled eglue_type");
00218     }
00219   }
00220 
00221 
00222 
00223 template<typename eglue_type>
00224 template<typename T1, typename T2>
00225 arma_hot
00226 inline
00227 void
00228 eglue_core<eglue_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
00229   {
00230   arma_extra_debug_sigprint();
00231   
00232   typedef typename T1::elem_type eT;
00233   
00234   const Proxy<T1>& P1 = x.P1;
00235   const Proxy<T2>& P2 = x.P2;
00236   
00237   arma_assert_same_size(out.n_rows, out.n_cols, P1.n_rows, P1.n_cols, "element-wise matrix multiplication");
00238   
00239         eT* out_mem = out.memptr();
00240   const u32 n_elem  = P1.n_elem;
00241   
00242        if(is_same_type<eglue_type, eglue_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] + P2[i]; }
00243   else if(is_same_type<eglue_type, eglue_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] - P2[i]; }
00244   else if(is_same_type<eglue_type, eglue_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] / P2[i]; }
00245   else if(is_same_type<eglue_type, eglue_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] *= P1[i] * P2[i]; }
00246   else
00247     {
00248     arma_stop("eglue_core::apply_inplace_schur(): unhandled eglue_type");
00249     }
00250   }
00251 
00252 
00253 
00254 template<typename eglue_type>
00255 template<typename T1, typename T2>
00256 arma_hot
00257 inline
00258 void
00259 eglue_core<eglue_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, const eGlue<T1, T2, eglue_type>& x)
00260   {
00261   arma_extra_debug_sigprint();
00262   
00263   typedef typename T1::elem_type eT;
00264   
00265   const Proxy<T1>& P1 = x.P1;
00266   const Proxy<T2>& P2 = x.P2;
00267   
00268   arma_assert_same_size(out.n_rows, out.n_cols, P1.n_rows, P1.n_cols, "element-wise matrix division");
00269   
00270         eT* out_mem = out.memptr();
00271   const u32 n_elem  = P1.n_elem;
00272   
00273        if(is_same_type<eglue_type, eglue_plus >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] + P2[i]; }
00274   else if(is_same_type<eglue_type, eglue_minus>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] - P2[i]; }
00275   else if(is_same_type<eglue_type, eglue_div  >::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] / P2[i]; }
00276   else if(is_same_type<eglue_type, eglue_schur>::value == true) for(u32 i=0; i<n_elem; ++i) { out_mem[i] /= P1[i] * P2[i]; }
00277   else
00278     {
00279     arma_stop("eglue_core::apply_inplace_div(): unhandled eglue_type");
00280     }
00281   }
00282 
00283 
00284 
00285 //! @}