glue_times_meat.hpp
Go to the documentation of this file.
00001 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au)
00002 // Copyright (C) 2008-2011 Conrad Sanderson
00003 // 
00004 // This file is part of the Armadillo C++ library.
00005 // It is provided without any warranty of fitness
00006 // for any purpose. You can redistribute this file
00007 // and/or modify it under the terms of the GNU
00008 // Lesser General Public License (LGPL) as published
00009 // by the Free Software Foundation, either version 3
00010 // of the License or (at your option) any later version.
00011 // (see http://www.opensource.org/licenses for more info)
00012 
00013 
00016 
00017 
00018 
00019 template<uword N>
00020 template<typename T1, typename T2>
00021 inline
00022 void
00023 glue_times_redirect<N>::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
00024   {
00025   arma_extra_debug_sigprint();
00026   
00027   typedef typename T1::elem_type eT;
00028   
00029   const partial_unwrap_check<T1> tmp1(X.A, out);
00030   const partial_unwrap_check<T2> tmp2(X.B, out);
00031   
00032   const Mat<eT>& A = tmp1.M;
00033   const Mat<eT>& B = tmp2.M;
00034   
00035   const bool do_trans_A = tmp1.do_trans;
00036   const bool do_trans_B = tmp2.do_trans;
00037 
00038   const bool use_alpha = tmp1.do_times || tmp2.do_times;
00039   const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val()) : eT(0);
00040   
00041   glue_times::apply(out, A, B, alpha, do_trans_A, do_trans_B, use_alpha);
00042   }
00043 
00044 
00045 
00046 template<typename T1, typename T2, typename T3>
00047 inline
00048 void
00049 glue_times_redirect<3>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue<T1,T2,glue_times>, T3, glue_times>& X)
00050   {
00051   arma_extra_debug_sigprint();
00052   
00053   typedef typename T1::elem_type eT;
00054   
00055   // there is exactly 3 objects
00056   // hence we can safely expand X as X.A.A, X.A.B and X.B
00057   
00058   const partial_unwrap_check<T1> tmp1(X.A.A, out);
00059   const partial_unwrap_check<T2> tmp2(X.A.B, out);
00060   const partial_unwrap_check<T3> tmp3(X.B,   out);
00061   
00062   const Mat<eT>& A = tmp1.M;
00063   const Mat<eT>& B = tmp2.M;
00064   const Mat<eT>& C = tmp3.M;
00065   
00066   const bool do_trans_A = tmp1.do_trans;
00067   const bool do_trans_B = tmp2.do_trans;
00068   const bool do_trans_C = tmp3.do_trans;
00069   
00070   const bool use_alpha = tmp1.do_times || tmp2.do_times || tmp3.do_times;
00071   const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * tmp3.get_val()) : eT(0);
00072   
00073   glue_times::apply(out, A, B, C, alpha, do_trans_A, do_trans_B, do_trans_C, use_alpha);
00074   }
00075 
00076 
00077 
00078 template<typename T1, typename T2, typename T3, typename T4>
00079 inline
00080 void
00081 glue_times_redirect<4>::apply(Mat<typename T1::elem_type>& out, const Glue< Glue< Glue<T1,T2,glue_times>, T3, glue_times>, T4, glue_times>& X)
00082   {
00083   arma_extra_debug_sigprint();
00084   
00085   typedef typename T1::elem_type eT;
00086   
00087   // there is exactly 4 objects
00088   // hence we can safely expand X as X.A.A.A, X.A.A.B, X.A.B and X.B
00089   
00090   const partial_unwrap_check<T1> tmp1(X.A.A.A, out);
00091   const partial_unwrap_check<T2> tmp2(X.A.A.B, out);
00092   const partial_unwrap_check<T3> tmp3(X.A.B,   out);
00093   const partial_unwrap_check<T4> tmp4(X.B,     out);
00094   
00095   const Mat<eT>& A = tmp1.M;
00096   const Mat<eT>& B = tmp2.M;
00097   const Mat<eT>& C = tmp3.M;
00098   const Mat<eT>& D = tmp4.M;
00099   
00100   const bool do_trans_A = tmp1.do_trans;
00101   const bool do_trans_B = tmp2.do_trans;
00102   const bool do_trans_C = tmp3.do_trans;
00103   const bool do_trans_D = tmp4.do_trans;
00104   
00105   const bool use_alpha = tmp1.do_times || tmp2.do_times || tmp3.do_times || tmp4.do_times;
00106   const eT       alpha = use_alpha ? (tmp1.get_val() * tmp2.get_val() * tmp3.get_val() * tmp4.get_val()) : eT(0);
00107   
00108   glue_times::apply(out, A, B, C, D, alpha, do_trans_A, do_trans_B, do_trans_C, do_trans_D, use_alpha);
00109   }
00110 
00111 
00112 
00113 template<typename T1, typename T2>
00114 inline
00115 void
00116 glue_times::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X)
00117   {
00118   arma_extra_debug_sigprint();
00119 
00120   typedef typename T1::elem_type eT;
00121 
00122   const sword N_mat = 1 + depth_lhs< glue_times, Glue<T1,T2,glue_times> >::num;
00123 
00124   arma_extra_debug_print(arma_boost::format("N_mat = %d") % N_mat);
00125 
00126   glue_times_redirect<N_mat>::apply(out, X);
00127   }
00128 
00129 
00130 
00131 template<typename T1>
00132 inline
00133 void
00134 glue_times::apply_inplace(Mat<typename T1::elem_type>& out, const T1& X)
00135   {
00136   arma_extra_debug_sigprint();
00137   
00138   typedef typename T1::elem_type eT;
00139   
00140   const unwrap_check<T1> tmp(X, out);
00141   const Mat<eT>& B     = tmp.M;
00142   
00143   arma_debug_assert_mul_size(out, B, "matrix multiplication");
00144   
00145   const uword out_n_rows = out.n_rows;
00146   const uword out_n_cols = out.n_cols;
00147   
00148   if(out_n_cols == B.n_cols)
00149     {
00150     // size of resulting matrix is the same as 'out'
00151     
00152     podarray<eT> tmp(out_n_cols);
00153     
00154     eT* tmp_rowdata = tmp.memptr();
00155     
00156     for(uword row=0; row < out_n_rows; ++row)
00157       {
00158       tmp.copy_row(out, row);
00159       
00160       for(uword col=0; col < out_n_cols; ++col)
00161         {
00162         out.at(row,col) = op_dot::direct_dot( out_n_cols, tmp_rowdata, B.colptr(col) );
00163         }
00164       }
00165     
00166     }
00167   else
00168     {
00169     const Mat<eT> tmp(out);
00170     glue_times::apply(out, tmp, B, eT(1), false, false, false);
00171     }
00172   
00173   }
00174 
00175 
00176 
00177 template<typename T1, typename T2>
00178 arma_hot
00179 inline
00180 void
00181 glue_times::apply_inplace_plus(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times>& X, const sword sign)
00182   {
00183   arma_extra_debug_sigprint();
00184   
00185   typedef typename T1::elem_type eT;
00186   
00187   const partial_unwrap_check<T1> tmp1(X.A, out);
00188   const partial_unwrap_check<T2> tmp2(X.B, out);
00189   
00190   const Mat<eT>& A     = tmp1.M;
00191   const Mat<eT>& B     = tmp2.M;
00192   const eT       alpha = tmp1.get_val() * tmp2.get_val() * ( (sign > sword(0)) ? eT(1) : eT(-1) );
00193   
00194   const bool do_trans_A = tmp1.do_trans;
00195   const bool do_trans_B = tmp2.do_trans;
00196   const bool use_alpha  = tmp1.do_times || tmp2.do_times || (sign < sword(0));
00197   
00198   arma_debug_assert_mul_size(A, B, do_trans_A, do_trans_B, "matrix multiplication");
00199   
00200   const uword result_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
00201   const uword result_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
00202   
00203   arma_assert_same_size(out.n_rows, out.n_cols, result_n_rows, result_n_cols, "addition");
00204   
00205   if(out.n_elem > 0)
00206     {
00207     if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) )
00208       {
00209       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00210         {
00211         gemv<true,         false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00212         }
00213       else
00214       if(B.n_cols == 1)
00215         {
00216         gemv<false,        false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00217         }
00218       else
00219         {
00220         gemm<false, false, false, true>::apply(out, A, B, alpha, eT(1));
00221         }
00222       }
00223     else
00224     if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == true) )
00225       {
00226       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00227         {
00228         gemv<true,         true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00229         }
00230       else
00231       if(B.n_cols == 1)
00232         {
00233         gemv<false,        true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00234         }
00235       else
00236         {
00237         gemm<false, false, true, true>::apply(out, A, B, alpha, eT(1));
00238         }
00239       }
00240     else
00241     if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == false) )
00242       {
00243       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00244         {
00245         gemv<true,        false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00246         }
00247       else
00248       if(B.n_cols == 1)
00249         {
00250         gemv<true,        false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00251         }
00252       else
00253         {
00254         gemm<true, false, false, true>::apply(out, A, B, alpha, eT(1));
00255         }
00256       }
00257     else
00258     if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == true) )
00259       {
00260       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00261         {
00262         gemv<true,        true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00263         }
00264       else
00265       if(B.n_cols == 1)
00266         {
00267         gemv<true,        true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00268         }
00269       else
00270         {
00271         gemm<true, false, true, true>::apply(out, A, B, alpha, eT(1));
00272         }
00273       }
00274     else
00275     if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == false) )
00276       {
00277       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00278         {
00279         gemv<false,       false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00280         }
00281       else
00282       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00283         {
00284         gemv<false,       false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00285         }
00286       else
00287         {
00288         gemm<false, true, false, true>::apply(out, A, B, alpha, eT(1));
00289         }
00290       }
00291     else
00292     if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == true) )
00293       {
00294       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00295         {
00296         gemv<false,       true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00297         }
00298       else
00299       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00300         {
00301         gemv<false,       true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00302         }
00303       else
00304         {
00305         gemm<false, true, true, true>::apply(out, A, B, alpha, eT(1));
00306         }
00307       }
00308     else
00309     if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == false) )
00310       {
00311       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00312         {
00313         gemv<false,      false, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00314         }
00315       else
00316       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00317         {
00318         gemv<true,       false, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00319         }
00320       else
00321         {
00322         gemm<true, true, false, true>::apply(out, A, B, alpha, eT(1));
00323         }
00324       }
00325     else
00326     if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == true) )
00327       {
00328       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00329         {
00330         gemv<false,      true, true>::apply(out.memptr(), B, A.memptr(), alpha, eT(1));
00331         }
00332       else
00333       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00334         {
00335         gemv<true,       true, true>::apply(out.memptr(), A, B.memptr(), alpha, eT(1));
00336         }
00337       else
00338         {
00339         gemm<true, true, true, true>::apply(out, A, B, alpha, eT(1));
00340         }
00341       }
00342     }
00343   
00344   
00345   }
00346 
00347 
00348 
00349 template<typename eT>
00350 arma_inline
00351 uword
00352 glue_times::mul_storage_cost(const Mat<eT>& A, const Mat<eT>& B, const bool do_trans_A, const bool do_trans_B)
00353   {
00354   const uword final_A_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
00355   const uword final_B_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
00356   
00357   return final_A_n_rows * final_B_n_cols;
00358   }
00359 
00360 
00361 
00362 template<typename eT>
00363 arma_hot
00364 inline
00365 void
00366 glue_times::apply
00367   (
00368         Mat<eT>& out,
00369   const Mat<eT>& A,
00370   const Mat<eT>& B,
00371   const eT       alpha,
00372   const bool     do_trans_A,
00373   const bool     do_trans_B,
00374   const bool     use_alpha
00375   )
00376   {
00377   arma_extra_debug_sigprint();
00378   
00379   arma_debug_assert_mul_size(A, B, do_trans_A, do_trans_B, "matrix multiplication");
00380   
00381   const uword final_n_rows = (do_trans_A == false) ? A.n_rows : A.n_cols;
00382   const uword final_n_cols = (do_trans_B == false) ? B.n_cols : B.n_rows;
00383   
00384   out.set_size(final_n_rows, final_n_cols);
00385   
00386   if( (A.n_elem > 0) && (B.n_elem > 0) )
00387     {
00388     if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == false) )
00389       {
00390       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00391         {
00392         gemv<true,         false, false>::apply(out.memptr(), B, A.memptr());
00393         }
00394       else
00395       if(B.n_cols == 1)
00396         {
00397         gemv<false,        false, false>::apply(out.memptr(), A, B.memptr());
00398         }
00399       else
00400         {
00401         gemm<false, false, false, false>::apply(out, A, B);
00402         }
00403       }
00404     else
00405     if( (do_trans_A == false) && (do_trans_B == false) && (use_alpha == true) )
00406       {
00407       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00408         {
00409         gemv<true,         true, false>::apply(out.memptr(), B, A.memptr(), alpha);
00410         }
00411       else
00412       if(B.n_cols == 1)
00413         {
00414         gemv<false,        true, false>::apply(out.memptr(), A, B.memptr(), alpha);
00415         }
00416       else
00417         {
00418         gemm<false, false, true, false>::apply(out, A, B, alpha);
00419         }
00420       }
00421     else
00422     if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == false) )
00423       {
00424       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00425         {
00426         gemv<true,        false, false>::apply(out.memptr(), B, A.memptr());
00427         }
00428       else
00429       if(B.n_cols == 1)
00430         {
00431         gemv<true,        false, false>::apply(out.memptr(), A, B.memptr());
00432         }
00433       else
00434         {
00435         gemm<true, false, false, false>::apply(out, A, B);
00436         }
00437       }
00438     else
00439     if( (do_trans_A == true) && (do_trans_B == false) && (use_alpha == true) )
00440       {
00441       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00442         {
00443         gemv<true,        true, false>::apply(out.memptr(), B, A.memptr(), alpha);
00444         }
00445       else
00446       if(B.n_cols == 1)
00447         {
00448         gemv<true,        true, false>::apply(out.memptr(), A, B.memptr(), alpha);
00449         }
00450       else
00451         {
00452         gemm<true, false, true, false>::apply(out, A, B, alpha);
00453         }
00454       }
00455     else
00456     if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == false) )
00457       {
00458       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00459         {
00460         gemv<false,       false, false>::apply(out.memptr(), B, A.memptr());
00461         }
00462       else
00463       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00464         {
00465         gemv<false,       false, false>::apply(out.memptr(), A, B.memptr());
00466         }
00467       else
00468         {
00469         gemm<false, true, false, false>::apply(out, A, B);
00470         }
00471       }
00472     else
00473     if( (do_trans_A == false) && (do_trans_B == true) && (use_alpha == true) )
00474       {
00475       if( (A.n_rows == 1) && (is_complex<eT>::value == false) )
00476         {
00477         gemv<false,       true, false>::apply(out.memptr(), B, A.memptr(), alpha);
00478         }
00479       else
00480       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00481         {
00482         gemv<false,       true, false>::apply(out.memptr(), A, B.memptr(), alpha);
00483         }
00484       else
00485         {
00486         gemm<false, true, true, false>::apply(out, A, B, alpha);
00487         }
00488       }
00489     else
00490     if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == false) )
00491       {
00492       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00493         {
00494         gemv<false,      false, false>::apply(out.memptr(), B, A.memptr());
00495         }
00496       else
00497       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00498         {
00499         gemv<true,       false, false>::apply(out.memptr(), A, B.memptr());
00500         }
00501       else
00502         {
00503         gemm<true, true, false, false>::apply(out, A, B);
00504         }
00505       }
00506     else
00507     if( (do_trans_A == true) && (do_trans_B == true) && (use_alpha == true) )
00508       {
00509       if( (A.n_cols == 1) && (is_complex<eT>::value == false) )
00510         {
00511         gemv<false,      true, false>::apply(out.memptr(), B, A.memptr(), alpha);
00512         }
00513       else
00514       if( (B.n_rows == 1) && (is_complex<eT>::value == false) )
00515         {
00516         gemv<true,       true, false>::apply(out.memptr(), A, B.memptr(), alpha);
00517         }
00518       else
00519         {
00520         gemm<true, true, true, false>::apply(out, A, B, alpha);
00521         }
00522       }
00523     }
00524   else
00525     {
00526     out.zeros();
00527     }
00528   }
00529 
00530 
00531 
00532 template<typename eT>
00533 inline
00534 void
00535 glue_times::apply
00536   (
00537         Mat<eT>& out,
00538   const Mat<eT>& A,
00539   const Mat<eT>& B,
00540   const Mat<eT>& C,
00541   const eT       alpha,
00542   const bool     do_trans_A,
00543   const bool     do_trans_B,
00544   const bool     do_trans_C,
00545   const bool     use_alpha
00546   )
00547   {
00548   arma_extra_debug_sigprint();
00549   
00550   Mat<eT> tmp;
00551   
00552   if( glue_times::mul_storage_cost(A, B, do_trans_A, do_trans_B) <= glue_times::mul_storage_cost(B, C, do_trans_B, do_trans_C) )
00553     {
00554     // out = (A*B)*C
00555     glue_times::apply(tmp, A,   B, alpha, do_trans_A, do_trans_B, use_alpha);
00556     glue_times::apply(out, tmp, C, eT(0), false,      do_trans_C, false    );
00557     }
00558   else
00559     {
00560     // out = A*(B*C)
00561     glue_times::apply(tmp, B, C,   alpha, do_trans_B, do_trans_C, use_alpha);
00562     glue_times::apply(out, A, tmp, eT(0), do_trans_A, false,      false    );
00563     }
00564   }
00565 
00566 
00567 
00568 template<typename eT>
00569 inline
00570 void
00571 glue_times::apply
00572   (
00573         Mat<eT>& out,
00574   const Mat<eT>& A,
00575   const Mat<eT>& B,
00576   const Mat<eT>& C,
00577   const Mat<eT>& D,
00578   const eT       alpha,
00579   const bool     do_trans_A,
00580   const bool     do_trans_B,
00581   const bool     do_trans_C,
00582   const bool     do_trans_D,
00583   const bool     use_alpha
00584   )
00585   {
00586   arma_extra_debug_sigprint();
00587   
00588   Mat<eT> tmp;
00589   
00590   if( glue_times::mul_storage_cost(A, C, do_trans_A, do_trans_C) <= glue_times::mul_storage_cost(B, D, do_trans_B, do_trans_D) )
00591     {
00592     // out = (A*B*C)*D
00593     glue_times::apply(tmp, A, B, C, alpha, do_trans_A, do_trans_B, do_trans_C, use_alpha);
00594     
00595     glue_times::apply(out, tmp, D, eT(0), false, do_trans_D, false);
00596     }
00597   else
00598     {
00599     // out = A*(B*C*D)
00600     glue_times::apply(tmp, B, C, D, alpha, do_trans_B, do_trans_C, do_trans_D, use_alpha);
00601     
00602     glue_times::apply(out, A, tmp, eT(0), do_trans_A, false, false);
00603     }
00604   }
00605 
00606 
00607 
00608 //
00609 // glue_times_diag
00610 
00611 
00612 template<typename T1, typename T2>
00613 arma_hot
00614 inline
00615 void
00616 glue_times_diag::apply(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_times_diag>& X)
00617   {
00618   arma_extra_debug_sigprint();
00619   
00620   typedef typename T1::elem_type eT;
00621   
00622   const strip_diagmat<T1> S1(X.A);
00623   const strip_diagmat<T2> S2(X.B);
00624   
00625   typedef typename strip_diagmat<T1>::stored_type T1_stripped;
00626   typedef typename strip_diagmat<T2>::stored_type T2_stripped;
00627   
00628   if( (S1.do_diagmat == true) && (S2.do_diagmat == false) )
00629     {
00630     const diagmat_proxy_check<T1_stripped> A(S1.M, out);
00631     
00632     const unwrap_check<T2> tmp(X.B, out);
00633     const Mat<eT>& B     = tmp.M;
00634     
00635     arma_debug_assert_mul_size(A.n_elem, A.n_elem, B.n_rows, B.n_cols, "matrix multiplication");
00636     
00637     out.set_size(A.n_elem, B.n_cols);
00638     
00639     for(uword col=0; col<B.n_cols; ++col)
00640       {
00641             eT* out_coldata = out.colptr(col);
00642       const eT* B_coldata   = B.colptr(col);
00643       
00644       for(uword row=0; row<B.n_rows; ++row)
00645         {
00646         out_coldata[row] = A[row] * B_coldata[row];
00647         }
00648       }
00649     }
00650   else
00651   if( (S1.do_diagmat == false) && (S2.do_diagmat == true) )
00652     {
00653     const unwrap_check<T1> tmp(X.A, out);
00654     const Mat<eT>& A     = tmp.M;
00655     
00656     const diagmat_proxy_check<T2_stripped> B(S2.M, out);
00657     
00658     arma_debug_assert_mul_size(A.n_rows, A.n_cols, B.n_elem, B.n_elem, "matrix multiplication");
00659     
00660     out.set_size(A.n_rows, B.n_elem);
00661     
00662     for(uword col=0; col<A.n_cols; ++col)
00663       {
00664       const eT  val = B[col];
00665       
00666             eT* out_coldata = out.colptr(col);
00667       const eT*   A_coldata =   A.colptr(col);
00668     
00669       for(uword row=0; row<A.n_rows; ++row)
00670         {
00671         out_coldata[row] = A_coldata[row] * val;
00672         }
00673       }
00674     }
00675   else
00676   if( (S1.do_diagmat == true) && (S2.do_diagmat == true) )
00677     {
00678     const diagmat_proxy_check<T1_stripped> A(S1.M, out);
00679     const diagmat_proxy_check<T2_stripped> B(S2.M, out);
00680     
00681     arma_debug_assert_mul_size(A.n_elem, A.n_elem, B.n_elem, B.n_elem, "matrix multiplication");
00682     
00683     out.zeros(A.n_elem, A.n_elem);
00684     
00685     for(uword i=0; i<A.n_elem; ++i)
00686       {
00687       out.at(i,i) = A[i] * B[i];
00688       }
00689     }
00690   }
00691 
00692 
00693 


armadillo_matrix
Author(s): Conrad Sanderson - NICTA (www.nicta.com.au), (Wrapper by Sjoerd van den Dries)
autogenerated on Tue Jan 7 2014 11:42:04