glue_div_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 glue_div
00017 //! @{
00018 
00019 
00020 
00021 template<typename T1, typename T2>
00022 inline
00023 void
00024 glue_div::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_div>& X)
00025   {
00026   arma_extra_debug_sigprint();
00027 
00028   typedef typename T1::elem_type eT;
00029 
00030   const u32 N_mat = 1 + depth_lhs< glue_div, Glue<T1,T2,glue_div> >::num;
00031   arma_extra_debug_print( arma_boost::format("N_mat = %d") % N_mat );
00032 
00033   if(N_mat == 2)
00034     {
00035     if(is_Mat<T1>::value == false)
00036       {
00037       out = X.A;
00038       glue_div::apply_inplace(out, X.B);
00039       }
00040     else
00041       {
00042       const unwrap<T1> tmp1(X.A);
00043       const unwrap<T2> tmp2(X.B);
00044       
00045       glue_div::apply(out, tmp1.M, tmp2.M);
00046       }
00047     }
00048   else
00049     {
00050     const Mat<eT>* ptrs[N_mat];
00051     bool            del[N_mat];
00052 
00053     mat_ptrs<glue_div, Glue<T1,T2,glue_div> >::get_ptrs(ptrs, del, X);
00054     //mat_ptrs_outcheck<glue_div, Glue<T1,T2,glue_div> >::get_ptrs(ptrs, del, X, &out);
00055 
00056     for(u32 i=0; i<N_mat; ++i)  arma_extra_debug_print( arma_boost::format("ptrs[%d] = %x") % i % ptrs[i] );
00057     for(u32 i=0; i<N_mat; ++i)  arma_extra_debug_print( arma_boost::format(" del[%d] = %d") % i %  del[i] );
00058 
00059     const Mat<eT>& tmp_mat = *(ptrs[0]);
00060 
00061     for(u32 i=1; i<N_mat; ++i)
00062       {
00063       arma_debug_assert_same_size(tmp_mat, *(ptrs[i]), "element-wise matrix division");
00064       }
00065   
00066     
00067     const u32 n_rows = ptrs[0]->n_rows;
00068     const u32 n_cols = ptrs[0]->n_cols;
00069 
00070     // no aliasing problem
00071     out.set_size(n_rows,n_cols);
00072     
00073     const u32 n_elem = ptrs[0]->n_elem;
00074     
00075     for(u32 j=0; j<n_elem; ++j)
00076       {
00077       eT acc = ptrs[0]->mem[j];
00078       
00079       for(u32 i=1; i<N_mat; ++i)
00080         {
00081         acc /= ptrs[i]->mem[j];
00082         }
00083       
00084       out[j] = acc;
00085       }
00086     
00087     
00088     for(u32 i=0; i<N_mat; ++i)
00089       {
00090       if(del[i] == true)
00091         {
00092         arma_extra_debug_print( arma_boost::format("delete ptrs[%d]") % i );
00093         delete ptrs[i];
00094         }
00095       }
00096 
00097     }
00098   }
00099 
00100 
00101 
00102 template<typename T1>
00103 inline
00104 void
00105 glue_div::apply_inplace(Mat<typename T1::elem_type>& out, const T1& X)
00106   {
00107   arma_extra_debug_sigprint();
00108   
00109   typedef typename T1::elem_type eT;
00110   
00111   const unwrap<T1>   tmp(X);
00112   const Mat<eT>& B = tmp.M;
00113   
00114   arma_debug_assert_same_size(out, B, "element-wise matrix division");
00115   
00116   const u32 n_elem = out.n_elem;
00117   
00118         eT* out_mem = out.memptr();
00119   const eT* B_mem   = B.mem;
00120   
00121   for(u32 i=0; i<n_elem; ++i)
00122     {
00123     out_mem[i] /= B_mem[i];
00124     }
00125   
00126   }
00127 
00128 
00129 
00130 //! element-wise division with different element types
00131 template<typename eT1, typename eT2>
00132 inline
00133 void
00134 glue_div::apply_mixed(Mat<typename promote_type<eT1,eT2>::result>& out, const Mat<eT1>& X, const Mat<eT2>& Y)
00135   {
00136   arma_extra_debug_sigprint();
00137   
00138   typedef typename promote_type<eT1,eT2>::result out_eT;
00139   
00140   arma_debug_assert_same_size(X,Y, "element-wise matrix division");
00141   
00142   //out.set_size(X.n_rows, X.n_cols);
00143   out.copy_size(X);
00144   
00145         out_eT* out_mem = out.memptr();
00146   const eT1*    X_mem   = X.mem;
00147   const eT2*    Y_mem   = Y.mem;
00148   
00149   const u32 n_elem = out.n_elem;
00150   
00151   for(u32 i=0; i<n_elem; ++i)
00152     {
00153     out_mem[i] = upgrade_val<eT1,eT2>::apply(X_mem[i]) / upgrade_val<eT1,eT2>::apply(Y_mem[i]);
00154     }
00155   }
00156 
00157 
00158 
00159 template<typename eT>
00160 inline
00161 void
00162 glue_div::apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
00163   {
00164   arma_extra_debug_sigprint();
00165   
00166   arma_debug_assert_same_size(A, B, "element-wise matrix division");
00167     
00168   // no aliasing problem
00169   //out.set_size(A.n_rows, A.n_cols);
00170   out.copy_size(A);
00171     
00172   const u32 n_elem = A.n_elem;
00173 
00174         eT* out_mem = out.memptr();
00175   const eT* A_mem   = A.mem;
00176   const eT* B_mem   = B.mem;
00177     
00178   for(u32 i=0; i<n_elem; ++i)
00179     {
00180     out_mem[i] = A_mem[i] / B_mem[i];
00181     }
00182   
00183   }
00184 
00185 
00186 
00187 template<typename eT>
00188 inline
00189 void
00190 glue_div::apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C)
00191   {
00192   arma_extra_debug_sigprint();
00193   
00194   arma_debug_assert_same_size(A, B, "element-wise matrix division");
00195   arma_debug_assert_same_size(B, C, "element-wise matrix division");
00196   
00197   // no aliasing problem
00198   //out.set_size(A.n_rows, A.n_cols);
00199   out.copy_size(A);
00200   
00201   const u32 n_elem = A.n_elem;
00202   
00203         eT* out_mem = out.memptr();
00204   const eT* A_mem   = A.mem;
00205   const eT* B_mem   = B.mem;
00206   const eT* C_mem   = C.mem;
00207   
00208   for(u32 i=0; i<n_elem; ++i)
00209     {
00210     out_mem[i] = A_mem[i] / B_mem[i] / C_mem[i];
00211     }
00212   
00213   }
00214 
00215 
00216 #if defined(ARMA_GOOD_COMPILER)
00217 
00218 
00219 template<typename eT>
00220 inline
00221 void
00222 glue_div::apply(Mat<eT>& out, const Glue<Mat<eT>,Mat<eT>,glue_div>& X)
00223   {
00224   glue_div::apply(out, X.A, X.B);
00225   }
00226 
00227 
00228 
00229 template<typename eT>
00230 inline
00231 void
00232 glue_div::apply(Mat<eT>& out, const Glue< Glue<Mat<eT>,Mat<eT>,glue_div>, Mat<eT>,glue_div>& X)
00233   {
00234   glue_div::apply(out, X.A.A, X.A.B, X.B);
00235   }
00236 
00237 
00238 
00239 #endif
00240 
00241 
00242 
00243 //! @}