00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 template<typename eT>
00020 inline
00021 void
00022 glue_schur::apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
00023 {
00024 arma_extra_debug_sigprint();
00025
00026 arma_debug_assert_same_size(A, B, "matrix schur product");
00027
00028
00029 out.set_size(A.n_rows, A.n_cols);
00030
00031 eT* out_mem = out.memptr();
00032 const eT* A_mem = A.mem;
00033 const eT* B_mem = B.mem;
00034
00035 const u32 n_elem = A.n_elem;
00036
00037 for(u32 i=0; i<n_elem; ++i)
00038 {
00039 out_mem[i] = A_mem[i] * B_mem[i];
00040 }
00041
00042 }
00043
00044
00045
00046 template<typename eT>
00047 inline
00048 void
00049 glue_schur::apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B, const Mat<eT>& C)
00050 {
00051 arma_extra_debug_sigprint();
00052
00053 arma_debug_assert_same_size(A, B, "matrix schur product");
00054 arma_debug_assert_same_size(A, C, "matrix schur product");
00055
00056
00057 out.set_size(A.n_rows, A.n_cols);
00058
00059 eT* out_mem = out.memptr();
00060 const eT* A_mem = A.mem;
00061 const eT* B_mem = B.mem;
00062 const eT* C_mem = C.mem;
00063
00064 const u32 n_elem = A.n_elem;
00065
00066 for(u32 i=0; i<n_elem; ++i)
00067 {
00068 out_mem[i] = A_mem[i] * B_mem[i] * C_mem[i];
00069 }
00070
00071 }
00072
00073
00074
00075 template<typename eT>
00076 inline
00077 void
00078 glue_schur::apply(Mat<eT>& out, const Glue<Mat<eT>,Mat<eT>,glue_schur>& X)
00079 {
00080 glue_schur::apply(out, X.A, X.B);
00081 }
00082
00083
00084
00085 template<typename eT>
00086 inline
00087 void
00088 glue_schur::apply(Mat<eT>& out, const Glue< Glue<Mat<eT>,Mat<eT>,glue_schur>, Mat<eT>,glue_schur>& X)
00089 {
00090 glue_schur::apply(out, X.A.A, X.A.B, X.B);
00091 }
00092
00093
00094
00095 template<typename T1, typename T2>
00096 void
00097 glue_schur::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_schur>& X)
00098 {
00099 arma_extra_debug_sigprint();
00100
00101 typedef typename T1::elem_type eT;
00102
00103 const u32 N_mat = 1 + depth_lhs< glue_schur, Glue<T1,T2,glue_schur> >::num;
00104 arma_extra_debug_print( arma_boost::format("N_mat = %d") % N_mat );
00105
00106 if(N_mat == 2)
00107 {
00108 const unwrap<T1> tmp1(X.A);
00109 const unwrap<T2> tmp2(X.B);
00110
00111 glue_schur::apply(out, tmp1.M, tmp2.M);
00112 }
00113 else
00114 {
00115 const Mat<eT>* ptrs[N_mat];
00116 bool del[N_mat];
00117
00118 mat_ptrs<glue_schur, Glue<T1,T2,glue_schur> >::get_ptrs(ptrs, del, X);
00119
00120
00121 for(u32 i=0; i<N_mat; ++i) arma_extra_debug_print( arma_boost::format("ptrs[%d] = %x") % i % ptrs[i] );
00122 for(u32 i=0; i<N_mat; ++i) arma_extra_debug_print( arma_boost::format(" del[%d] = %d") % i % del[i] );
00123
00124 const Mat<eT>& tmp_mat = *(ptrs[0]);
00125
00126 for(u32 i=1; i<N_mat; ++i)
00127 {
00128 arma_debug_assert_same_size(tmp_mat, *(ptrs[i]), "matrix schur product");
00129 }
00130
00131
00132 const u32 n_rows = ptrs[0]->n_rows;
00133 const u32 n_cols = ptrs[0]->n_cols;
00134
00135
00136 out.set_size(n_rows,n_cols);
00137
00138 const u32 n_elem = ptrs[0]->n_elem;
00139
00140 for(u32 j=0; j<n_elem; ++j)
00141 {
00142 eT acc = ptrs[0]->mem[j];
00143
00144 for(u32 i=1; i<N_mat; ++i)
00145 {
00146 acc *= ptrs[i]->mem[j];
00147 }
00148
00149 out[j] = acc;
00150 }
00151
00152
00153 for(u32 i=0; i<N_mat; ++i)
00154 {
00155 if(del[i] == true)
00156 {
00157 arma_extra_debug_print( arma_boost::format("delete ptrs[%d]") % i );
00158 delete ptrs[i];
00159 }
00160 }
00161
00162 }
00163 }
00164
00165
00166
00167 template<typename eT>
00168 inline
00169 void
00170 glue_schur::apply_inplace(Mat<eT>& out, const Mat<eT>& B)
00171 {
00172 arma_extra_debug_sigprint();
00173
00174 arma_debug_assert_same_size(out, B, "matrix schur product");
00175
00176 const u32 n_elem = out.n_elem;
00177
00178 for(u32 i=0; i<n_elem; ++i)
00179 {
00180 out[i] *= B.mem[i];
00181 }
00182
00183 }
00184
00185
00186
00187 template<typename T1, typename op_type>
00188 inline
00189 void
00190 glue_schur::apply_inplace(Mat<typename T1::elem_type>& out, const Op<T1, op_type>& X)
00191 {
00192 arma_extra_debug_sigprint();
00193
00194 typedef typename T1::elem_type eT;
00195
00196 const Mat<eT> tmp(X);
00197 glue_schur::apply(out, out, tmp);
00198 }
00199
00200
00201
00202 template<typename T1, typename T2, typename glue_type>
00203 inline
00204 void
00205 glue_schur::apply_inplace(Mat<typename T1::elem_type>& out, const Glue<T1, T2, glue_type>& X)
00206 {
00207 arma_extra_debug_sigprint();
00208
00209
00210
00211 typedef typename T1::elem_type eT;
00212
00213 const Mat<eT> tmp(X);
00214 glue_schur::apply(out, out, tmp);
00215 }
00216
00217
00218
00219
00220
00221
00222 template<typename eT1, typename eT2>
00223 inline
00224 void
00225 glue_schur::apply_mixed(Mat<typename promote_type<eT1,eT2>::result>& out, const Mat<eT1>& X, const Mat<eT2>& Y)
00226 {
00227 arma_extra_debug_sigprint();
00228
00229 typedef typename promote_type<eT1,eT2>::result out_eT;
00230
00231 arma_debug_assert_same_size(X,Y, "matrix schur product");
00232
00233 out.set_size(X.n_rows, X.n_cols);
00234
00235 out_eT* out_mem = out.memptr();
00236 const eT1* X_mem = X.mem;
00237 const eT2* Y_mem = Y.mem;
00238
00239 const u32 n_elem = out.n_elem;
00240
00241 for(u32 i=0; i<n_elem; ++i)
00242 {
00243 out_mem[i] = upgrade_val<eT1,eT2>::apply(X_mem[i]) * upgrade_val<eT1,eT2>::apply(Y_mem[i]);
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 template<typename T1, typename T2>
00254 inline
00255 void
00256 glue_schur_diag::apply(Mat<typename T1::elem_type>& out, const T1& A_orig, const Op<T2,op_diagmat>& B_orig)
00257 {
00258 arma_extra_debug_sigprint();
00259
00260 isnt_same_type<typename T1::elem_type, typename T2::elem_type>::check();
00261
00262 const unwrap<T1> tmp1(A_orig);
00263 const unwrap<T2> tmp2(B_orig.m);
00264
00265 typedef typename T1::elem_type eT;
00266
00267 const Mat<eT>& A = tmp1.M;
00268 const Mat<eT>& B = tmp2.M;
00269
00270 arma_debug_check( (B.is_square() == false), "glue_schur_diag::apply(): matrices must be square" );
00271 arma_debug_assert_same_size(A, B, "matrix schur product");
00272
00273 if( (&out != &A) && (&out != &B) )
00274 {
00275 out.zeros(A.n_rows, A.n_cols);
00276
00277 for(u32 i=0; i<A.n_rows; ++i)
00278 {
00279 out.at(i,i) = A.at(i,i) * B.at(i,i);
00280 }
00281 }
00282 else
00283 {
00284 for(u32 col=0; col<A.n_cols; ++col)
00285 {
00286 for(u32 row=0; row<A.n_rows; ++row)
00287 {
00288 if(col != row)
00289 {
00290 out.at(row,col) = eT(0);
00291 }
00292 else
00293 {
00294 out.at(row,col) = A.at(row,col) * B.at(row,col);
00295 }
00296 }
00297 }
00298 }
00299
00300 }
00301
00302
00303
00304 template<typename T1, typename T2>
00305 inline
00306 void
00307 glue_schur_diag::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagmat>& A_orig, const Op<T2,op_diagmat>& B_orig)
00308 {
00309 arma_extra_debug_sigprint();
00310
00311 isnt_same_type<typename T1::elem_type, typename T2::elem_type>::check();
00312
00313 const unwrap<T1> tmp1(A_orig.m);
00314 const unwrap<T2> tmp2(B_orig.m);
00315
00316 typedef typename T1::elem_type eT;
00317
00318 const Mat<eT>& A = tmp1.M;
00319 const Mat<eT>& B = tmp2.M;
00320
00321 arma_debug_check( (A.is_square() == false), "glue_schur_diag::apply(): matrices must be square" );
00322 arma_debug_assert_same_size(A, B, "matrix schur product");
00323
00324 if( (&out != &A) && (&out != &B) )
00325 {
00326 out.zeros(A.n_rows, A.n_cols);
00327
00328 for(u32 i=0; i<A.n_rows; ++i)
00329 {
00330 out.at(i,i) = A.at(i,i) * B.at(i,i);
00331 }
00332 }
00333 else
00334 {
00335 for(u32 col=0; col<A.n_cols; ++col)
00336 {
00337 for(u32 row=0; row<A.n_rows; ++row)
00338 {
00339 if(col != row)
00340 {
00341 out.at(row,col) = eT(0);
00342 }
00343 else
00344 {
00345 out.at(row,col) = A.at(row,col) * B.at(row,col);
00346 }
00347 }
00348 }
00349 }
00350
00351 }
00352
00353
00354
00355 template<typename T1, typename T2>
00356 inline
00357 void
00358 glue_schur_diag::apply(Mat<typename T1::elem_type>& out, const Glue<T1, Op<T2,op_diagmat>, glue_schur_diag>& X)
00359 {
00360 glue_schur_diag::apply(out, X.A, X.B);
00361 }
00362
00363
00364
00365 template<typename T1, typename T2>
00366 inline
00367 void
00368 glue_schur_diag::apply(Mat<typename T1::elem_type>& out, const Glue<Op<T1,op_diagmat>, T2, glue_schur_diag>& X)
00369 {
00370 glue_schur_diag::apply(out, X.B, X.A);
00371 }
00372
00373
00374
00375 template<typename T1, typename T2>
00376 inline
00377 void
00378 glue_schur_diag::apply(Mat<typename T1::elem_type>& out, const Glue<Op<T1,op_diagmat>, Op<T2,op_diagmat>, glue_schur_diag>& X)
00379 {
00380 glue_schur_diag::apply(out, X.A, X.B);
00381 }
00382
00383
00384