$search
00001 // Copyright (C) 2010-2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2010-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 #undef arma_applier_1 00019 #undef arma_applier_2 00020 #undef arma_applier_3 00021 #undef operatorA 00022 00023 #define arma_applier_1(operatorA) \ 00024 {\ 00025 uword i,j;\ 00026 \ 00027 for(i=0, j=1; j<n_elem; i+=2, j+=2)\ 00028 {\ 00029 eT tmp_i = P[i];\ 00030 eT tmp_j = P[j];\ 00031 \ 00032 tmp_i = eop_core<eop_type>::process(tmp_i, k);\ 00033 tmp_j = eop_core<eop_type>::process(tmp_j, k);\ 00034 \ 00035 out_mem[i] operatorA tmp_i;\ 00036 out_mem[j] operatorA tmp_j;\ 00037 }\ 00038 \ 00039 if(i < n_elem)\ 00040 {\ 00041 out_mem[i] operatorA eop_core<eop_type>::process(P[i], k);\ 00042 }\ 00043 } 00044 00045 00046 #define arma_applier_2(operatorA) \ 00047 {\ 00048 uword count = 0;\ 00049 \ 00050 for(uword col=0; col<n_cols; ++col)\ 00051 {\ 00052 uword i,j;\ 00053 \ 00054 for(i=0, j=1; j<n_rows; i+=2, j+=2, count+=2)\ 00055 {\ 00056 eT tmp_i = P.at(i,col);\ 00057 eT tmp_j = P.at(j,col);\ 00058 \ 00059 tmp_i = eop_core<eop_type>::process(tmp_i, k);\ 00060 tmp_j = eop_core<eop_type>::process(tmp_j, k);\ 00061 \ 00062 out_mem[count ] operatorA tmp_i;\ 00063 out_mem[count+1] operatorA tmp_j;\ 00064 }\ 00065 \ 00066 if(i < n_rows)\ 00067 {\ 00068 out_mem[count] operatorA eop_core<eop_type>::process(P.at(i,col), k);\ 00069 ++count;\ 00070 }\ 00071 }\ 00072 } 00073 00074 00075 00076 #define arma_applier_3(operatorA) \ 00077 {\ 00078 uword count = 0;\ 00079 \ 00080 for(uword slice=0; slice<n_slices; ++slice)\ 00081 {\ 00082 for(uword col=0; col<n_cols; ++col)\ 00083 {\ 00084 uword i,j;\ 00085 \ 00086 for(i=0, j=1; j<n_rows; i+=2, j+=2, count+=2)\ 00087 {\ 00088 eT tmp_i = P.at(i,col,slice);\ 00089 eT tmp_j = P.at(j,col,slice);\ 00090 \ 00091 tmp_i = eop_core<eop_type>::process(tmp_i, k);\ 00092 tmp_j = eop_core<eop_type>::process(tmp_j, k);\ 00093 \ 00094 out_mem[count ] operatorA tmp_i;\ 00095 out_mem[count+1] operatorA tmp_j;\ 00096 }\ 00097 \ 00098 if(i < n_rows)\ 00099 {\ 00100 out_mem[count] operatorA eop_core<eop_type>::process(P.at(i,col,slice), k);\ 00101 ++count;\ 00102 }\ 00103 }\ 00104 }\ 00105 } 00106 00107 00108 00109 // 00110 // matrices 00111 00112 00113 00114 template<typename eop_type> 00115 template<typename T1> 00116 arma_hot 00117 inline 00118 void 00119 eop_core<eop_type>::apply(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x) 00120 { 00121 arma_extra_debug_sigprint(); 00122 00123 typedef typename T1::elem_type eT; 00124 00125 const uword n_rows = out.n_rows; 00126 const uword n_cols = out.n_cols; 00127 const uword n_elem = out.n_elem; 00128 00129 // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing; 00130 // size setting and alias checking is done by either the Mat contructor or operator=() 00131 00132 const eT k = x.aux; 00133 eT* out_mem = out.memptr(); 00134 00135 if(Proxy<T1>::prefer_at_accessor == false) 00136 { 00137 typename Proxy<T1>::ea_type P = x.P.get_ea(); 00138 00139 arma_applier_1(=); 00140 } 00141 else 00142 { 00143 const Proxy<T1>& P = x.P; 00144 00145 arma_applier_2(=); 00146 } 00147 } 00148 00149 00150 00151 template<typename eop_type> 00152 template<typename T1> 00153 arma_hot 00154 inline 00155 void 00156 eop_core<eop_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x) 00157 { 00158 arma_extra_debug_sigprint(); 00159 00160 typedef typename T1::elem_type eT; 00161 00162 const uword n_rows = x.get_n_rows(); 00163 const uword n_cols = x.get_n_cols(); 00164 00165 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "addition"); 00166 00167 eT* out_mem = out.memptr(); 00168 const uword n_elem = out.n_elem; 00169 00170 const eT k = x.aux; 00171 00172 if(Proxy<T1>::prefer_at_accessor == false) 00173 { 00174 typename Proxy<T1>::ea_type P = x.P.get_ea(); 00175 00176 arma_applier_1(+=); 00177 } 00178 else 00179 { 00180 const Proxy<T1>& P = x.P; 00181 00182 arma_applier_2(+=); 00183 } 00184 } 00185 00186 00187 00188 template<typename eop_type> 00189 template<typename T1> 00190 arma_hot 00191 inline 00192 void 00193 eop_core<eop_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x) 00194 { 00195 arma_extra_debug_sigprint(); 00196 00197 typedef typename T1::elem_type eT; 00198 00199 const uword n_rows = x.get_n_rows(); 00200 const uword n_cols = x.get_n_cols(); 00201 00202 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "subtraction"); 00203 00204 eT* out_mem = out.memptr(); 00205 const uword n_elem = out.n_elem; 00206 00207 const eT k = x.aux; 00208 00209 if(Proxy<T1>::prefer_at_accessor == false) 00210 { 00211 typename Proxy<T1>::ea_type P = x.P.get_ea(); 00212 00213 arma_applier_1(-=); 00214 } 00215 else 00216 { 00217 const Proxy<T1>& P = x.P; 00218 00219 arma_applier_2(-=); 00220 } 00221 } 00222 00223 00224 00225 template<typename eop_type> 00226 template<typename T1> 00227 arma_hot 00228 inline 00229 void 00230 eop_core<eop_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x) 00231 { 00232 arma_extra_debug_sigprint(); 00233 00234 typedef typename T1::elem_type eT; 00235 00236 const uword n_rows = x.get_n_rows(); 00237 const uword n_cols = x.get_n_cols(); 00238 00239 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise multiplication"); 00240 00241 eT* out_mem = out.memptr(); 00242 const uword n_elem = out.n_elem; 00243 00244 const eT k = x.aux; 00245 00246 if(Proxy<T1>::prefer_at_accessor == false) 00247 { 00248 typename Proxy<T1>::ea_type P = x.P.get_ea(); 00249 00250 arma_applier_1(*=); 00251 } 00252 else 00253 { 00254 const Proxy<T1>& P = x.P; 00255 00256 arma_applier_2(*=); 00257 } 00258 } 00259 00260 00261 00262 template<typename eop_type> 00263 template<typename T1> 00264 arma_hot 00265 inline 00266 void 00267 eop_core<eop_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, const eOp<T1, eop_type>& x) 00268 { 00269 arma_extra_debug_sigprint(); 00270 00271 typedef typename T1::elem_type eT; 00272 00273 const uword n_rows = x.get_n_rows(); 00274 const uword n_cols = x.get_n_cols(); 00275 00276 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise division"); 00277 00278 eT* out_mem = out.memptr(); 00279 const uword n_elem = out.n_elem; 00280 00281 const eT k = x.aux; 00282 00283 if(Proxy<T1>::prefer_at_accessor == false) 00284 { 00285 typename Proxy<T1>::ea_type P = x.P.get_ea(); 00286 00287 arma_applier_1(/=); 00288 } 00289 else 00290 { 00291 const Proxy<T1>& P = x.P; 00292 00293 arma_applier_2(/=); 00294 } 00295 } 00296 00297 00298 00299 // 00300 // cubes 00301 00302 00303 00304 template<typename eop_type> 00305 template<typename T1> 00306 arma_hot 00307 inline 00308 void 00309 eop_core<eop_type>::apply(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x) 00310 { 00311 arma_extra_debug_sigprint(); 00312 00313 typedef typename T1::elem_type eT; 00314 00315 const uword n_rows = out.n_rows; 00316 const uword n_cols = out.n_cols; 00317 const uword n_slices = out.n_slices; 00318 const uword n_elem = out.n_elem; 00319 00320 // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing; 00321 // size setting and alias checking is done by either the Mat contructor or operator=() 00322 00323 const eT k = x.aux; 00324 eT* out_mem = out.memptr(); 00325 00326 if(ProxyCube<T1>::prefer_at_accessor == false) 00327 { 00328 typename ProxyCube<T1>::ea_type P = x.P.get_ea(); 00329 00330 arma_applier_1(=); 00331 } 00332 else 00333 { 00334 const ProxyCube<T1>& P = x.P; 00335 00336 arma_applier_3(=); 00337 } 00338 } 00339 00340 00341 00342 template<typename eop_type> 00343 template<typename T1> 00344 arma_hot 00345 inline 00346 void 00347 eop_core<eop_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x) 00348 { 00349 arma_extra_debug_sigprint(); 00350 00351 typedef typename T1::elem_type eT; 00352 00353 const uword n_rows = x.get_n_rows(); 00354 const uword n_cols = x.get_n_cols(); 00355 const uword n_slices = x.get_n_slices(); 00356 00357 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "addition"); 00358 00359 eT* out_mem = out.memptr(); 00360 const uword n_elem = out.n_elem; 00361 00362 const eT k = x.aux; 00363 00364 if(ProxyCube<T1>::prefer_at_accessor == false) 00365 { 00366 typename ProxyCube<T1>::ea_type P = x.P.get_ea(); 00367 00368 arma_applier_1(+=); 00369 } 00370 else 00371 { 00372 const ProxyCube<T1>& P = x.P; 00373 00374 arma_applier_3(+=); 00375 } 00376 } 00377 00378 00379 00380 template<typename eop_type> 00381 template<typename T1> 00382 arma_hot 00383 inline 00384 void 00385 eop_core<eop_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x) 00386 { 00387 arma_extra_debug_sigprint(); 00388 00389 typedef typename T1::elem_type eT; 00390 00391 const uword n_rows = x.get_n_rows(); 00392 const uword n_cols = x.get_n_cols(); 00393 const uword n_slices = x.get_n_slices(); 00394 00395 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "subtraction"); 00396 00397 eT* out_mem = out.memptr(); 00398 const uword n_elem = out.n_elem; 00399 00400 const eT k = x.aux; 00401 00402 if(ProxyCube<T1>::prefer_at_accessor == false) 00403 { 00404 typename ProxyCube<T1>::ea_type P = x.P.get_ea(); 00405 00406 arma_applier_1(-=); 00407 } 00408 else 00409 { 00410 const ProxyCube<T1>& P = x.P; 00411 00412 arma_applier_3(-=); 00413 } 00414 } 00415 00416 00417 00418 template<typename eop_type> 00419 template<typename T1> 00420 arma_hot 00421 inline 00422 void 00423 eop_core<eop_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x) 00424 { 00425 arma_extra_debug_sigprint(); 00426 00427 typedef typename T1::elem_type eT; 00428 00429 const uword n_rows = x.get_n_rows(); 00430 const uword n_cols = x.get_n_cols(); 00431 const uword n_slices = x.get_n_slices(); 00432 00433 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise multiplication"); 00434 00435 eT* out_mem = out.memptr(); 00436 const uword n_elem = out.n_elem; 00437 00438 const eT k = x.aux; 00439 00440 if(ProxyCube<T1>::prefer_at_accessor == false) 00441 { 00442 typename ProxyCube<T1>::ea_type P = x.P.get_ea(); 00443 00444 arma_applier_1(*=); 00445 } 00446 else 00447 { 00448 const ProxyCube<T1>& P = x.P; 00449 00450 arma_applier_3(*=); 00451 } 00452 } 00453 00454 00455 00456 template<typename eop_type> 00457 template<typename T1> 00458 arma_hot 00459 inline 00460 void 00461 eop_core<eop_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_type>& x) 00462 { 00463 arma_extra_debug_sigprint(); 00464 00465 typedef typename T1::elem_type eT; 00466 00467 const uword n_rows = x.get_n_rows(); 00468 const uword n_cols = x.get_n_cols(); 00469 const uword n_slices = x.get_n_slices(); 00470 00471 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, n_rows, n_cols, n_slices, "element-wise division"); 00472 00473 eT* out_mem = out.memptr(); 00474 const uword n_elem = out.n_elem; 00475 00476 const eT k = x.aux; 00477 00478 if(ProxyCube<T1>::prefer_at_accessor == false) 00479 { 00480 typename ProxyCube<T1>::ea_type P = x.P.get_ea(); 00481 00482 arma_applier_1(/=); 00483 } 00484 else 00485 { 00486 const ProxyCube<T1>& P = x.P; 00487 00488 arma_applier_3(/=); 00489 } 00490 } 00491 00492 00493 00494 // 00495 // common 00496 00497 00498 00499 template<typename eop_type> 00500 template<typename eT> 00501 arma_hot 00502 arma_pure 00503 arma_inline 00504 eT 00505 eop_core<eop_type>::process(const eT val, const eT k) 00506 { 00507 arma_ignore(val); 00508 arma_ignore(k); 00509 00510 arma_stop("eop_core::process(): unhandled eop_type"); 00511 return eT(0); 00512 } 00513 00514 00515 00516 template<> template<typename eT> arma_hot arma_const arma_inline eT 00517 eop_core<eop_scalar_plus >::process(const eT val, const eT k) { return val + k; } 00518 00519 template<> template<typename eT> arma_hot arma_const arma_inline eT 00520 eop_core<eop_scalar_minus_pre >::process(const eT val, const eT k) { return k - val; } 00521 00522 template<> template<typename eT> arma_hot arma_const arma_inline eT 00523 eop_core<eop_scalar_minus_post>::process(const eT val, const eT k) { return val - k; } 00524 00525 template<> template<typename eT> arma_hot arma_const arma_inline eT 00526 eop_core<eop_scalar_times >::process(const eT val, const eT k) { return val * k; } 00527 00528 template<> template<typename eT> arma_hot arma_const arma_inline eT 00529 eop_core<eop_scalar_div_pre >::process(const eT val, const eT k) { return k / val; } 00530 00531 template<> template<typename eT> arma_hot arma_const arma_inline eT 00532 eop_core<eop_scalar_div_post >::process(const eT val, const eT k) { return val / k; } 00533 00534 template<> template<typename eT> arma_hot arma_const arma_inline eT 00535 eop_core<eop_square >::process(const eT val, const eT ) { return val*val; } 00536 00537 template<> template<typename eT> arma_hot arma_const arma_inline eT 00538 eop_core<eop_neg >::process(const eT val, const eT ) { return eop_aux::neg(val); } 00539 00540 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00541 eop_core<eop_sqrt >::process(const eT val, const eT ) { return eop_aux::sqrt(val); } 00542 00543 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00544 eop_core<eop_log >::process(const eT val, const eT ) { return eop_aux::log(val); } 00545 00546 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00547 eop_core<eop_log2 >::process(const eT val, const eT ) { return eop_aux::log2(val); } 00548 00549 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00550 eop_core<eop_log10 >::process(const eT val, const eT ) { return eop_aux::log10(val); } 00551 00552 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00553 eop_core<eop_trunc_log >::process(const eT val, const eT ) { return arma::trunc_log(val); } 00554 00555 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00556 eop_core<eop_exp >::process(const eT val, const eT ) { return eop_aux::exp(val); } 00557 00558 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00559 eop_core<eop_exp2 >::process(const eT val, const eT ) { return eop_aux::exp2(val); } 00560 00561 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00562 eop_core<eop_exp10 >::process(const eT val, const eT ) { return eop_aux::exp10(val); } 00563 00564 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00565 eop_core<eop_trunc_exp >::process(const eT val, const eT ) { return arma::trunc_exp(val); } 00566 00567 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00568 eop_core<eop_cos >::process(const eT val, const eT ) { return eop_aux::cos(val); } 00569 00570 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00571 eop_core<eop_sin >::process(const eT val, const eT ) { return eop_aux::sin(val); } 00572 00573 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00574 eop_core<eop_tan >::process(const eT val, const eT ) { return eop_aux::tan(val); } 00575 00576 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00577 eop_core<eop_acos >::process(const eT val, const eT ) { return eop_aux::acos(val); } 00578 00579 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00580 eop_core<eop_asin >::process(const eT val, const eT ) { return eop_aux::asin(val); } 00581 00582 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00583 eop_core<eop_atan >::process(const eT val, const eT ) { return eop_aux::atan(val); } 00584 00585 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00586 eop_core<eop_cosh >::process(const eT val, const eT ) { return eop_aux::cosh(val); } 00587 00588 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00589 eop_core<eop_sinh >::process(const eT val, const eT ) { return eop_aux::sinh(val); } 00590 00591 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00592 eop_core<eop_tanh >::process(const eT val, const eT ) { return eop_aux::tanh(val); } 00593 00594 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00595 eop_core<eop_acosh >::process(const eT val, const eT ) { return eop_aux::acosh(val); } 00596 00597 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00598 eop_core<eop_asinh >::process(const eT val, const eT ) { return eop_aux::asinh(val); } 00599 00600 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00601 eop_core<eop_atanh >::process(const eT val, const eT ) { return eop_aux::atanh(val); } 00602 00603 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00604 eop_core<eop_eps >::process(const eT val, const eT ) { return eop_aux::direct_eps(val); } 00605 00606 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00607 eop_core<eop_abs >::process(const eT val, const eT ) { return eop_aux::arma_abs(val); } 00608 00609 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00610 eop_core<eop_conj >::process(const eT val, const eT ) { return eop_aux::conj(val); } 00611 00612 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00613 eop_core<eop_pow >::process(const eT val, const eT k) { return eop_aux::pow(val, k); } 00614 00615 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00616 eop_core<eop_floor >::process(const eT val, const eT ) { return eop_aux::floor(val); } 00617 00618 template<> template<typename eT> arma_hot arma_pure arma_inline eT 00619 eop_core<eop_ceil >::process(const eT val, const eT ) { return eop_aux::ceil(val); } 00620 00621 00622 00623 #undef arma_applier_1 00624 #undef arma_applier_2 00625 #undef arma_applier_3 00626 00627 00628