00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 template<typename eop_cube_type>
00023 template<typename T1>
00024 arma_hot
00025 arma_inline
00026 typename T1::elem_type
00027 eop_cube_core<eop_cube_type>::get_elem(const eOpCube<T1, eop_cube_type>& x, const u32 i)
00028 {
00029 typedef typename T1::elem_type eT;
00030
00031 if(is_cube_generator<eop_cube_type>::value == true) { return eop_aux::generate<eT,eop_cube_type>(); }
00032 else { return eop_cube_core<eop_cube_type>::process(x, x.P[i]); }
00033 }
00034
00035
00036
00037 template<typename eop_cube_type>
00038 template<typename T1>
00039 arma_hot
00040 arma_inline
00041 typename T1::elem_type
00042 eop_cube_core<eop_cube_type>::get_elem(const eOpCube<T1, eop_cube_type>& x, const u32 row, const u32 col, const u32 slice)
00043 {
00044 typedef typename T1::elem_type eT;
00045
00046 if(is_cube_generator<eop_cube_type>::value == true) { return eop_aux::generate<eT,eop_cube_type>(); }
00047 else { return eop_cube_core<eop_cube_type>::process(x, x.P.at(row,col,slice)); }
00048 }
00049
00050
00051
00052 template<typename eop_cube_type>
00053 template<typename T1>
00054 arma_hot
00055 arma_inline
00056 typename T1::elem_type
00057 eop_cube_core<eop_cube_type>::process(const eOpCube<T1, eop_cube_type>& x, const typename T1::elem_type val)
00058 {
00059 typedef typename T1::elem_type eT;
00060
00061
00062
00063 if(is_same_type<eop_cube_type, eop_cube_neg >::value == true) { return -val; }
00064 else if(is_same_type<eop_cube_type, eop_cube_scalar_plus >::value == true) { return val + x.aux; }
00065 else if(is_same_type<eop_cube_type, eop_cube_scalar_minus_pre >::value == true) { return x.aux - val; }
00066 else if(is_same_type<eop_cube_type, eop_cube_scalar_minus_post>::value == true) { return val - x.aux; }
00067 else if(is_same_type<eop_cube_type, eop_cube_scalar_times >::value == true) { return val * x.aux; }
00068 else if(is_same_type<eop_cube_type, eop_cube_scalar_div_pre >::value == true) { return x.aux / val; }
00069 else if(is_same_type<eop_cube_type, eop_cube_scalar_div_post >::value == true) { return val / x.aux; }
00070 else if(is_same_type<eop_cube_type, eop_cube_square >::value == true) { return val*val; }
00071 else if(is_same_type<eop_cube_type, eop_cube_sqrt >::value == true) { return eop_aux::sqrt(val); }
00072 else if(is_same_type<eop_cube_type, eop_cube_log10 >::value == true) { return eop_aux::log10(val); }
00073 else if(is_same_type<eop_cube_type, eop_cube_log >::value == true) { return eop_aux::log(val); }
00074 else if(is_same_type<eop_cube_type, eop_cube_trunc_log >::value == true) { return arma::trunc_log(val); }
00075 else if(is_same_type<eop_cube_type, eop_cube_exp >::value == true) { return eop_aux::exp(val); }
00076 else if(is_same_type<eop_cube_type, eop_cube_trunc_exp >::value == true) { return arma::trunc_exp(val); }
00077 else if(is_same_type<eop_cube_type, eop_cube_cos >::value == true) { return eop_aux::cos(val); }
00078 else if(is_same_type<eop_cube_type, eop_cube_cosh >::value == true) { return eop_aux::cosh(val); }
00079 else if(is_same_type<eop_cube_type, eop_cube_acos >::value == true) { return eop_aux::acos(val); }
00080 else if(is_same_type<eop_cube_type, eop_cube_acosh >::value == true) { return eop_aux::acosh(val); }
00081 else if(is_same_type<eop_cube_type, eop_cube_sin >::value == true) { return eop_aux::sin(val); }
00082 else if(is_same_type<eop_cube_type, eop_cube_sinh >::value == true) { return eop_aux::sinh(val); }
00083 else if(is_same_type<eop_cube_type, eop_cube_asin >::value == true) { return eop_aux::asin(val); }
00084 else if(is_same_type<eop_cube_type, eop_cube_asinh >::value == true) { return eop_aux::asinh(val); }
00085 else if(is_same_type<eop_cube_type, eop_cube_tan >::value == true) { return eop_aux::tan(val); }
00086 else if(is_same_type<eop_cube_type, eop_cube_tanh >::value == true) { return eop_aux::tanh(val); }
00087 else if(is_same_type<eop_cube_type, eop_cube_atan >::value == true) { return eop_aux::atan(val); }
00088 else if(is_same_type<eop_cube_type, eop_cube_atanh >::value == true) { return eop_aux::atanh(val); }
00089 else if(is_same_type<eop_cube_type, eop_cube_eps >::value == true) { return eop_aux::direct_eps(val);}
00090 else if(is_same_type<eop_cube_type, eop_cube_abs >::value == true) { return eop_aux::arma_abs(val); }
00091 else if(is_same_type<eop_cube_type, eop_cube_conj >::value == true) { return eop_aux::conj(val); }
00092 else if(is_same_type<eop_cube_type, eop_cube_pow >::value == true) { return eop_aux::pow(val, x.aux);}
00093 else if(is_same_type<eop_cube_type, eop_cube_pow_int >::value == true)
00094 {
00095 const int exponent = (x.aux_u32_b == 0) ? int(x.aux_u32_a) : -int(x.aux_u32_a);
00096
00097 return eop_aux::pow_int(val, exponent);
00098 }
00099 else
00100 {
00101 arma_stop("eop_cube_core::process(): unhandled eop_cube_type");
00102 return eT(0);
00103 }
00104 }
00105
00106
00107
00108 template<typename eop_cube_type>
00109 template<typename T1>
00110 arma_hot
00111 inline
00112 void
00113 eop_cube_core<eop_cube_type>::apply(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00114 {
00115 arma_extra_debug_sigprint();
00116
00117 if(is_Cube<T1>::value == true)
00118 {
00119 eop_cube_core<eop_cube_type>::apply_unwrap(out, x);
00120 }
00121 else
00122 {
00123 eop_cube_core<eop_cube_type>::apply_proxy(out, x);
00124 }
00125 }
00126
00127
00128
00129 template<typename eop_cube_type>
00130 template<typename T1>
00131 arma_hot
00132 inline
00133 void
00134 eop_cube_core<eop_cube_type>::apply_proxy(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00135 {
00136 arma_extra_debug_sigprint();
00137
00138
00139
00140
00141
00142 typedef typename T1::elem_type eT;
00143
00144 const ProxyCube<T1>& P = x.P;
00145
00146 out.set_size(P.n_rows, P.n_cols, P.n_slices);
00147
00148 eT* out_mem = out.memptr();
00149 const u32 n_elem = P.n_elem;
00150
00151 if(is_cube_generator<eop_cube_type>::value == true)
00152 {
00153 for(u32 i=0; i<n_elem; ++i)
00154 {
00155 out_mem[i] = eop_aux::generate<eT,eop_cube_type>();
00156 }
00157 }
00158 else
00159 {
00160 for(u32 i=0; i<n_elem; ++i)
00161 {
00162 out_mem[i] = eop_cube_core<eop_cube_type>::process(x, P[i]);
00163 }
00164 }
00165 }
00166
00167
00168
00169 template<typename eop_cube_type>
00170 template<typename T1>
00171 arma_hot
00172 inline
00173 void
00174 eop_cube_core<eop_cube_type>::apply_unwrap(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00175 {
00176 arma_extra_debug_sigprint();
00177
00178 typedef typename T1::elem_type eT;
00179
00180 const ProxyCube<T1>& P = x.P;
00181
00182 out.set_size(P.n_rows, P.n_cols, P.n_slices);
00183
00184 eT* out_mem = out.memptr();
00185 const u32 n_elem = P.n_elem;
00186
00187 if(is_cube_generator<eop_cube_type>::value == true)
00188 {
00189 for(u32 i=0; i<n_elem; ++i)
00190 {
00191 out_mem[i] = eop_aux::generate<eT,eop_cube_type>();
00192 }
00193 }
00194 else
00195 {
00196 const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);
00197
00198 const Cube<eT>& A = tmp.M;
00199 const eT* A_mem = A.memptr();
00200
00201 for(u32 i=0; i<n_elem; ++i)
00202 {
00203 out_mem[i] = eop_cube_core<eop_cube_type>::process(x, A_mem[i]);
00204 }
00205 }
00206 }
00207
00208
00209
00210 template<typename eop_cube_type>
00211 template<typename T1>
00212 arma_hot
00213 inline
00214 void
00215 eop_cube_core<eop_cube_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00216 {
00217 arma_extra_debug_sigprint();
00218
00219 typedef typename T1::elem_type eT;
00220
00221 const ProxyCube<T1>& P = x.P;
00222
00223 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "cube addition");
00224
00225 eT* out_mem = out.memptr();
00226 const u32 n_elem = P.n_elem;
00227
00228 if(is_cube_generator<eop_cube_type>::value == true)
00229 {
00230 for(u32 i=0; i<n_elem; ++i)
00231 {
00232 out_mem[i] += eop_aux::generate<eT,eop_cube_type>();
00233 }
00234 }
00235 else
00236 {
00237 for(u32 i=0; i<n_elem; ++i)
00238 {
00239 out_mem[i] += eop_cube_core<eop_cube_type>::process(x, P[i]);
00240 }
00241 }
00242 }
00243
00244
00245
00246 template<typename eop_cube_type>
00247 template<typename T1>
00248 arma_hot
00249 inline
00250 void
00251 eop_cube_core<eop_cube_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00252 {
00253 arma_extra_debug_sigprint();
00254
00255 typedef typename T1::elem_type eT;
00256
00257 const ProxyCube<T1>& P = x.P;
00258
00259 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "cube subtraction");
00260
00261 eT* out_mem = out.memptr();
00262 const u32 n_elem = P.n_elem;
00263
00264 if(is_cube_generator<eop_cube_type>::value == true)
00265 {
00266 for(u32 i=0; i<n_elem; ++i)
00267 {
00268 out_mem[i] -= eop_aux::generate<eT,eop_cube_type>();
00269 }
00270 }
00271 else
00272 {
00273 for(u32 i=0; i<n_elem; ++i)
00274 {
00275 out_mem[i] -= eop_cube_core<eop_cube_type>::process(x, P[i]);
00276 }
00277 }
00278 }
00279
00280
00281
00282 template<typename eop_cube_type>
00283 template<typename T1>
00284 arma_hot
00285 inline
00286 void
00287 eop_cube_core<eop_cube_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00288 {
00289 arma_extra_debug_sigprint();
00290
00291 typedef typename T1::elem_type eT;
00292
00293 const ProxyCube<T1>& P = x.P;
00294
00295 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "element-wise cube multiplication");
00296
00297 eT* out_mem = out.memptr();
00298 const u32 n_elem = P.n_elem;
00299
00300 if(is_cube_generator<eop_cube_type>::value == true)
00301 {
00302 for(u32 i=0; i<n_elem; ++i)
00303 {
00304 out_mem[i] *= eop_aux::generate<eT,eop_cube_type>();
00305 }
00306 }
00307 else
00308 {
00309 for(u32 i=0; i<n_elem; ++i)
00310 {
00311 out_mem[i] *= eop_cube_core<eop_cube_type>::process(x, P[i]);
00312 }
00313 }
00314 }
00315
00316
00317
00318 template<typename eop_cube_type>
00319 template<typename T1>
00320 arma_hot
00321 inline
00322 void
00323 eop_cube_core<eop_cube_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, const eOpCube<T1, eop_cube_type>& x)
00324 {
00325 arma_extra_debug_sigprint();
00326
00327 typedef typename T1::elem_type eT;
00328
00329 const ProxyCube<T1>& P = x.P;
00330
00331 arma_debug_assert_same_size(out.n_rows, out.n_cols, out.n_slices, P.n_rows, P.n_cols, P.n_slices, "element-wise cube division");
00332
00333 eT* out_mem = out.memptr();
00334 const u32 n_elem = P.n_elem;
00335
00336 if(is_cube_generator<eop_cube_type>::value == true)
00337 {
00338 for(u32 i=0; i<n_elem; ++i)
00339 {
00340 out_mem[i] /= eop_aux::generate<eT,eop_cube_type>();
00341 }
00342 }
00343 else
00344 {
00345 for(u32 i=0; i<n_elem; ++i)
00346 {
00347 out_mem[i] /= eop_cube_core<eop_cube_type>::process(x, P[i]);
00348 }
00349 }
00350 }
00351
00352
00353
00354