op_scalar_misc_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 
00017 //! \addtogroup op_scalar_misc
00018 //! @{
00019 
00020 //! Add a scalar to all elements of a matrix and store the result in a dense matrix
00021 template<typename T1>
00022 inline
00023 void
00024 op_scalar_plus::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_scalar_plus>& in)
00025   {
00026   arma_extra_debug_sigprint();
00027   
00028   typedef typename T1::elem_type eT;
00029   
00030   const unwrap<T1> tmp(in.m);
00031   const Mat<eT>& X = tmp.M;
00032   
00033   // no alias problems
00034   out.set_size(X.n_rows, X.n_cols);
00035   
00036         eT* out_mem = out.memptr();
00037   const eT* X_mem   = X.mem;
00038   const eT  k       = in.aux;
00039   
00040   for(u32 i=0; i<X.n_elem; ++i)
00041     {
00042     out_mem[i] = X_mem[i] + k;
00043     }
00044 
00045   }
00046 
00047 
00048 
00049 //! For each element of a matrix, subtract it from a scalar and store the result in a dense matrix
00050 template<typename T1>
00051 inline
00052 void
00053 op_scalar_minus_pre::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_scalar_minus_pre>& in)
00054   {
00055   arma_extra_debug_sigprint();
00056 
00057   typedef typename T1::elem_type eT;
00058   
00059   const unwrap<T1> tmp(in.m);
00060   const Mat<eT>& X = tmp.M;
00061   
00062   // no alias problems
00063   out.set_size(X.n_rows, X.n_cols);
00064   
00065         eT* out_mem = out.memptr();
00066   const eT* X_mem   = X.mem;
00067   const eT  k       = in.aux;
00068   
00069   for(u32 i=0; i<X.n_elem; ++i)
00070     {
00071     out_mem[i] = k - X_mem[i];
00072     }
00073 
00074   }
00075 
00076 
00077 
00078 //! subtract a scalar from each element of a matrix
00079 template<typename T1>
00080 inline
00081 void
00082 op_scalar_minus_post::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_scalar_minus_post>& in)
00083   {
00084   arma_extra_debug_sigprint();
00085 
00086   typedef typename T1::elem_type eT;
00087 
00088   const unwrap<T1> tmp(in.m);
00089   const Mat<eT>& X = tmp.M;
00090   
00091   // no alias problems
00092   out.set_size(X.n_rows, X.n_cols);
00093   
00094         eT* out_mem = out.memptr();
00095   const eT* X_mem   = X.mem;
00096   const eT  k       = in.aux;
00097   
00098   for(u32 i=0; i<X.n_elem; ++i)
00099     {
00100     out_mem[i] = X_mem[i] - k;
00101     }
00102 
00103   }
00104 
00105 
00106 
00107 //! Multiply all elements of a matrix by a scalar and store the result in a dense matrix
00108 template<typename T1>
00109 inline
00110 void
00111 op_scalar_times::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_scalar_times>& in)
00112   {
00113   arma_extra_debug_sigprint();
00114   
00115   typedef typename T1::elem_type eT;
00116   
00117   const unwrap<T1> tmp(in.m);
00118   const Mat<eT>& X = tmp.M;
00119   
00120   // no alias problems
00121   out.set_size(X.n_rows, X.n_cols);
00122         
00123         eT* out_mem = out.memptr();
00124   const eT* X_mem   = X.mem;
00125   const eT  k       = in.aux;
00126   
00127   for(u32 i=0; i < X.n_elem; ++i)
00128     {
00129     out_mem[i] = X_mem[i] * k;
00130     }
00131   
00132   }
00133 
00134 
00135   
00136 //! \brief 
00137 //! Evaluate Glue<T1,T2,glue_type>, and then multiply each element of the result by a scalar.
00138 //! Store the final result in a dense matrix.
00139 template<typename T1, typename T2, typename glue_type>
00140 inline
00141 void
00142 op_scalar_times::apply(Mat<typename T1::elem_type>& out, const Op<Glue<T1,T2,glue_type>, op_scalar_times>& in)
00143   {
00144   arma_extra_debug_sigprint();
00145   
00146   typedef typename T1::elem_type eT;
00147   
00148   out = in.m;  // implicit conversion to 'Mat<eT>'
00149   
00150         eT* out_mem = out.memptr();
00151   const eT        k = in.aux;
00152   const u32 n_elem  = out.n_elem;
00153   
00154   for(u32 i=0; i<n_elem; ++i)
00155     {
00156     out_mem[i] *= k;
00157     }
00158   }
00159   
00160   
00161 
00162 //! \brief 
00163 //! Evaluate A + B, and then multiply each element of the result by a scalar.
00164 //! Store the final result in a dense matrix.
00165 template<typename T1, typename T2>
00166 inline
00167 void
00168 op_scalar_times::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_plus>, op_scalar_times>& in)
00169   {
00170   arma_extra_debug_sigprint();
00171   
00172   const unwrap<T1> tmp1(in.m.A);
00173   const unwrap<T2> tmp2(in.m.B);
00174   
00175   typedef typename T1::elem_type eT;
00176   
00177   const Mat<eT>& A = tmp1.M;
00178   const Mat<eT>& B = tmp2.M;
00179   
00180   arma_debug_assert_same_size(A, B, "matrix addition");
00181   
00182   // no alias problems
00183   out.set_size(A.n_rows, A.n_cols);
00184   
00185         eT* out_mem = out.memptr();
00186   const eT* A_mem   = A.mem;
00187   const eT* B_mem   = B.mem;
00188   
00189   const eT  k       = in.aux;
00190   const u32 n_elem  = A.n_elem;
00191   
00192   for(u32 i=0; i<n_elem; ++i)
00193     {
00194     out_mem[i] = (A_mem[i] + B_mem[i]) * k;
00195     }
00196   
00197   }
00198 
00199 
00200 
00201 //! \brief 
00202 //! Evaluate A - B, and then multiply each element of the result by a scalar.
00203 //! Store the final result in a dense matrix.
00204 template<typename T1, typename T2>
00205 inline
00206 void
00207 op_scalar_times::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_minus>, op_scalar_times>& in)
00208   {
00209   arma_extra_debug_sigprint();
00210   
00211   const unwrap<T1> tmp1(in.m.A);
00212   const unwrap<T2> tmp2(in.m.B);
00213   
00214   typedef typename T1::elem_type eT;
00215   
00216   const Mat<eT>& A = tmp1.M;
00217   const Mat<eT>& B = tmp2.M;
00218   
00219   arma_debug_assert_same_size(A, B, "matrix subtraction");
00220   
00221   // no alias problems
00222   out.set_size(A.n_rows, A.n_cols);
00223   
00224         eT* out_mem = out.memptr();
00225   const eT* A_mem   = A.mem;
00226   const eT* B_mem   = B.mem;
00227   
00228   const eT  k       = in.aux;
00229   const u32 n_elem  = A.n_elem;
00230   
00231   for(u32 i=0; i<n_elem; ++i)
00232     {
00233     out_mem[i] = (A_mem[i] - B_mem[i]) * k;
00234     }
00235   
00236   }
00237 
00238 
00239 
00240 //! \brief 
00241 //! Evaluate A % B (where % is the element-wise multiply operation) and then multiply each element of the result by a scalar.
00242 //! Store the final result in a dense matrix.
00243 template<typename T1, typename T2>
00244 inline
00245 void
00246 op_scalar_times::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_schur>, op_scalar_times>& in)
00247   {
00248   arma_extra_debug_sigprint();
00249   
00250   const unwrap<T1> tmp1(in.m.A);
00251   const unwrap<T2> tmp2(in.m.B);
00252   
00253   typedef typename T1::elem_type eT;
00254   
00255   const Mat<eT>& A = tmp1.M;
00256   const Mat<eT>& B = tmp2.M;
00257   
00258   arma_debug_assert_same_size(A, B, "schur product");
00259   
00260   // no alias problems
00261   out.set_size(A.n_rows, A.n_cols);
00262   
00263         eT* out_mem = out.memptr();
00264   const eT* A_mem   = A.mem;
00265   const eT* B_mem   = B.mem;
00266   
00267   const eT  k       = in.aux;
00268   const u32 n_elem  = A.n_elem;
00269   
00270   for(u32 i=0; i<n_elem; ++i)
00271     {
00272     out_mem[i] = (A_mem[i] * B_mem[i]) * k;
00273     }
00274   
00275   }
00276 
00277 
00278 
00279 //
00280 // 
00281 // 
00282 
00283 
00284 
00285 template<typename T1>
00286 inline
00287 void
00288 op_scalar_div_pre::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_scalar_div_pre>& in)
00289   {
00290   arma_extra_debug_sigprint();
00291 
00292   typedef typename T1::elem_type eT;
00293   
00294   const unwrap<T1> tmp(in.m);
00295   const Mat<eT>& X = tmp.M;
00296   
00297   // TODO: analyse effects of aliasing
00298   out.set_size(X.n_rows, X.n_cols);
00299   
00300         eT* out_mem = out.memptr();
00301   const eT* X_mem   = X.mem;
00302   const eT  k       = in.aux;
00303   
00304   for(u32 i=0; i < X.n_elem; ++i)
00305     {
00306     out_mem[i] = k / X_mem[i];
00307     }
00308   
00309   }
00310 
00311 
00312   
00313 template<typename eT>
00314 inline
00315 void
00316 op_scalar_div_pre::apply(Mat<eT>& out, const Op<Mat<eT>,op_scalar_div_pre>& in)
00317   {
00318   arma_extra_debug_sigprint();
00319 
00320   const Mat<eT>& X = in.m;
00321   
00322   if(&out != &X)
00323     {
00324     out.set_size(X.n_rows, X.n_cols);
00325     
00326           eT* out_mem = out.memptr();
00327     const eT* X_mem   = X.mem;
00328     const eT  k       = in.aux;
00329     
00330     for(u32 i=0; i < X.n_elem; ++i)
00331       {
00332       out_mem[i] = k / X_mem[i];
00333       }
00334     }
00335   else
00336     {
00337           eT* out_mem = out.memptr();
00338     const eT  k       = in.aux;
00339     
00340     for(u32 i=0; i < out.n_elem; ++i)
00341       {
00342       out_mem[i] = k / out_mem[i];
00343       }
00344     
00345     }
00346   
00347   }
00348 
00349 
00350 
00351 template<typename T1, typename T2, typename glue_type>
00352 inline
00353 void
00354 op_scalar_div_pre::apply(Mat<typename T1::elem_type>& out, const Op<Glue<T1,T2,glue_type>, op_scalar_div_pre>& in)
00355   {
00356   arma_extra_debug_sigprint();
00357   
00358   typedef typename T1::elem_type eT;
00359   
00360   out = in.m;  // implicit conversion to 'Mat<eT>'
00361   
00362         eT* out_mem = out.memptr();
00363   const eT  k       = in.aux;
00364   const u32 n_elem  = out.n_elem;
00365   
00366   for(u32 i=0; i<n_elem; ++i)
00367     {
00368     out_mem[i] = k / out_mem[i];
00369     }
00370   }
00371 
00372 
00373 
00374 template<typename T1, typename T2>
00375 inline
00376 void
00377 op_scalar_div_pre::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_plus>, op_scalar_div_pre>& in)
00378   {
00379   arma_extra_debug_sigprint();
00380   
00381   unwrap<T1> tmp1(in.m.A);
00382   unwrap<T2> tmp2(in.m.B);
00383   
00384   typedef typename T1::elem_type eT;
00385   
00386   const Mat<eT>& A = tmp1.M;
00387   const Mat<eT>& B = tmp2.M;
00388   
00389   arma_debug_assert_same_size(A, B, "matrix addition");
00390   
00391   // no alias problems
00392   out.set_size(A.n_rows, A.n_cols);
00393   
00394         eT* out_mem = out.memptr();
00395   const eT* A_mem   = A.mem;
00396   const eT* B_mem   = B.mem;
00397   
00398   const eT  k       = in.aux;
00399   const u32 n_elem  = A.n_elem;
00400   
00401   for(u32 i=0; i<n_elem; ++i)
00402     {
00403     out_mem[i] = k / (A_mem[i] + B_mem[i]);
00404     }
00405   
00406   }
00407 
00408 
00409 
00410 template<typename T1, typename T2>
00411 inline
00412 void
00413 op_scalar_div_pre::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_minus>, op_scalar_div_pre>& in)
00414   {
00415   arma_extra_debug_sigprint();
00416   
00417   unwrap<T1> tmp1(in.m.A);
00418   unwrap<T2> tmp2(in.m.B);
00419   
00420   typedef typename T1::elem_type eT;
00421   
00422   const Mat<eT>& A = tmp1.M;
00423   const Mat<eT>& B = tmp2.M;
00424   
00425   arma_debug_assert_same_size(A, B, "matrix subtraction");
00426   
00427   // no alias problems
00428   out.set_size(A.n_rows, A.n_cols);
00429   
00430         eT* out_mem = out.memptr();
00431   const eT* A_mem   = A.mem;
00432   const eT* B_mem   = B.mem;
00433   
00434   const eT  k       = in.aux;
00435   const u32 n_elem  = A.n_elem;
00436   
00437   for(u32 i=0; i<n_elem; ++i)
00438     {
00439     out_mem[i] = k / (A_mem[i] - B_mem[i]);
00440     }
00441   
00442   }
00443 
00444 
00445 
00446 template<typename T1, typename T2>
00447 inline
00448 void
00449 op_scalar_div_pre::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_schur>, op_scalar_div_pre>& in)
00450   {
00451   arma_extra_debug_sigprint();
00452   
00453   unwrap<T1> tmp1(in.m.A);
00454   unwrap<T2> tmp2(in.m.B);
00455   
00456   typedef typename T1::elem_type eT;
00457   
00458   const Mat<eT>& A = tmp1.M;
00459   const Mat<eT>& B = tmp2.M;
00460   
00461   arma_debug_assert_same_size(A, B, "schur product");
00462   
00463   // no alias problems
00464   out.set_size(A.n_rows, A.n_cols);
00465   
00466         eT* out_mem = out.memptr();
00467   const eT* A_mem   = A.mem;
00468   const eT* B_mem   = B.mem;
00469   
00470   const eT  k       = in.aux;
00471   const u32 n_elem  = A.n_elem;
00472   
00473   for(u32 i=0; i<n_elem; ++i)
00474     {
00475     out_mem[i] = k / (A_mem[i] * B_mem[i]);
00476     }
00477   
00478   }
00479 
00480 
00481 
00482 //
00483 //
00484 //
00485 
00486 
00487 
00488 template<typename T1>
00489 inline
00490 void
00491 op_scalar_div_post::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_scalar_div_post>& in)
00492   {
00493   arma_extra_debug_sigprint();
00494 
00495   typedef typename T1::elem_type eT;
00496   
00497   const unwrap<T1> tmp(in.m);
00498   const Mat<eT>& X = tmp.M;
00499   
00500   // TODO: analyse effects of aliasing
00501   out.set_size(X.n_rows, X.n_cols);
00502   
00503         eT* out_mem = out.memptr();
00504   const eT* X_mem   = X.mem;
00505   const eT  k       = in.aux;
00506   
00507   for(u32 i=0; i < X.n_elem; ++i)
00508     {
00509     out_mem[i] = X_mem[i] / k;
00510     }
00511   
00512   }
00513 
00514 
00515 
00516 template<typename eT>
00517 inline
00518 void
00519 op_scalar_div_post::apply(Mat<eT>& out, const Op<Mat<eT>,op_scalar_div_post>& in)
00520   {
00521   arma_extra_debug_sigprint();
00522 
00523   const Mat<eT>& X = in.m;
00524   
00525   if(&out != &X)
00526     {
00527     out.set_size(X.n_rows, X.n_cols);
00528     
00529           eT* out_mem = out.memptr();
00530     const eT* X_mem   = X.mem;
00531     const eT  k       = in.aux;
00532     
00533     for(u32 i=0; i < X.n_elem; ++i)
00534       {
00535       out_mem[i] = X_mem[i] / k;
00536       }
00537     }
00538   else
00539     {
00540           eT* out_mem = out.memptr();
00541     const eT  k       = in.aux;
00542     
00543     for(u32 i=0; i < out.n_elem; ++i)
00544       {
00545       out_mem[i] /= k;
00546       }
00547     
00548     }
00549   
00550   }
00551 
00552 
00553 
00554 template<typename T1, typename T2, typename glue_type>
00555 inline
00556 void
00557 op_scalar_div_post::apply(Mat<typename T1::elem_type>& out, const Op<Glue<T1,T2,glue_type>, op_scalar_div_post>& in)
00558   {
00559   arma_extra_debug_sigprint();
00560   
00561   typedef typename T1::elem_type eT;
00562   
00563   out = in.m;  // implicit conversion to 'Mat<eT>'
00564   
00565         eT* out_mem = out.memptr();
00566   const eT  k       = in.aux;
00567   const u32 n_elem  = out.n_elem;
00568   
00569   for(u32 i=0; i<n_elem; ++i)
00570     {
00571     out_mem[i] /= k;
00572     }
00573   }
00574 
00575 
00576 
00577 template<typename T1, typename T2>
00578 inline
00579 void
00580 op_scalar_div_post::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_plus>, op_scalar_div_post>& in)
00581   {
00582   arma_extra_debug_sigprint();
00583   
00584   unwrap<T1> tmp1(in.m.A);
00585   unwrap<T2> tmp2(in.m.B);
00586   
00587   typedef typename T1::elem_type eT;
00588   
00589   const Mat<eT>& A = tmp1.M;
00590   const Mat<eT>& B = tmp2.M;
00591   
00592   arma_debug_assert_same_size(A, B, "matrix addition");
00593   
00594   // no alias problems
00595   out.set_size(A.n_rows, A.n_cols);
00596   
00597         eT* out_mem = out.memptr();
00598   const eT* A_mem   = A.mem;
00599   const eT* B_mem   = B.mem;
00600   
00601   const eT  k       = in.aux;
00602   const u32 n_elem  = A.n_elem;
00603   
00604   for(u32 i=0; i<n_elem; ++i)
00605     {
00606     out_mem[i] = (A_mem[i] + B_mem[i]) / k;
00607     }
00608   
00609   }
00610 
00611 
00612 
00613 template<typename T1, typename T2>
00614 inline
00615 void
00616 op_scalar_div_post::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_minus>, op_scalar_div_post>& in)
00617   {
00618   arma_extra_debug_sigprint();
00619   
00620   unwrap<T1> tmp1(in.m.A);
00621   unwrap<T2> tmp2(in.m.B);
00622   
00623   typedef typename T1::elem_type eT;
00624   
00625   const Mat<eT>& A = tmp1.M;
00626   const Mat<eT>& B = tmp2.M;
00627   
00628   arma_debug_assert_same_size(A, B, "matrix subtraction");
00629   
00630   // no alias problems
00631   out.set_size(A.n_rows, A.n_cols);
00632   
00633         eT* out_mem = out.memptr();
00634   const eT* A_mem   = A.mem;
00635   const eT* B_mem   = B.mem;
00636   
00637   const eT  k       = in.aux;
00638   const u32 n_elem  = A.n_elem;
00639   
00640   for(u32 i=0; i<n_elem; ++i)
00641     {
00642     out_mem[i] = (A_mem[i] - B_mem[i]) / k;
00643     }
00644   
00645   }
00646 
00647 
00648 
00649 template<typename T1, typename T2>
00650 inline
00651 void
00652 op_scalar_div_post::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_schur>, op_scalar_div_post>& in)
00653   {
00654   arma_extra_debug_sigprint();
00655   
00656   unwrap<T1> tmp1(in.m.A);
00657   unwrap<T2> tmp2(in.m.B);
00658   
00659   typedef typename T1::elem_type eT;
00660   
00661   const Mat<eT>& A = tmp1.M;
00662   const Mat<eT>& B = tmp2.M;
00663   
00664   arma_debug_assert_same_size(A, B, "schur product");
00665   
00666   // no alias problems
00667   out.set_size(A.n_rows, A.n_cols);
00668   
00669         eT* out_mem = out.memptr();
00670   const eT* A_mem   = A.mem;
00671   const eT* B_mem   = B.mem;
00672   
00673   const eT  k       = in.aux;
00674   const u32 n_elem  = A.n_elem;
00675   
00676   for(u32 i=0; i<n_elem; ++i)
00677     {
00678     out_mem[i] = (A_mem[i] * B_mem[i]) / k;
00679     }
00680   
00681   }
00682 
00683 
00684 
00685 //! @}