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