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