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