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