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