00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00016
00017
00018
00019 template<typename eT>
00020 arma_inline
00021 eT
00022 op_median::robust_mean(const eT A, const eT B)
00023 {
00024 return A + (B - A)/eT(2);
00025 }
00026
00027
00028
00030 template<typename eT>
00031 inline
00032 eT
00033 op_median::direct_median(std::vector<eT>& X)
00034 {
00035 arma_extra_debug_sigprint();
00036
00037 const uword n_elem = X.size();
00038 const uword half = n_elem/2;
00039
00040 std::sort(X.begin(), X.end());
00041
00042 if((n_elem % 2) == 0)
00043 {
00044 return op_median::robust_mean(X[half-1], X[half]);
00045 }
00046 else
00047 {
00048 return X[half];
00049 }
00050 }
00051
00052
00053
00054 template<typename eT>
00055 inline
00056 eT
00057 op_median::direct_median(const eT* X, const uword n_elem)
00058 {
00059 arma_extra_debug_sigprint();
00060
00061 std::vector<eT> tmp(X, X+n_elem);
00062
00063 return op_median::direct_median(tmp);
00064 }
00065
00066
00067
00068 template<typename eT>
00069 inline
00070 eT
00071 op_median::direct_median(const subview<eT>& X)
00072 {
00073 arma_extra_debug_sigprint();
00074
00075 const uword X_n_elem = X.n_elem;
00076
00077 std::vector<eT> tmp(X_n_elem);
00078
00079 for(uword i=0; i<X_n_elem; ++i)
00080 {
00081 tmp[i] = X[i];
00082 }
00083
00084 return op_median::direct_median(tmp);
00085 }
00086
00087
00088
00089 template<typename eT>
00090 inline
00091 eT
00092 op_median::direct_median(const diagview<eT>& X)
00093 {
00094 arma_extra_debug_sigprint();
00095
00096 const uword X_n_elem = X.n_elem;
00097
00098 std::vector<eT> tmp(X_n_elem);
00099
00100 for(uword i=0; i<X_n_elem; ++i)
00101 {
00102 tmp[i] = X[i];
00103 }
00104
00105 return op_median::direct_median(tmp);
00106 }
00107
00108
00109
00114 template<typename T1>
00115 inline
00116 void
00117 op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
00118 {
00119 arma_extra_debug_sigprint();
00120
00121 typedef typename T1::elem_type eT;
00122
00123 const unwrap_check<T1> tmp(in.m, out);
00124 const Mat<eT>& X = tmp.M;
00125
00126 const uword X_n_rows = X.n_rows;
00127 const uword X_n_cols = X.n_cols;
00128
00129 const uword dim = in.aux_uword_a;
00130 arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
00131
00132 if(dim == 0)
00133 {
00134 arma_extra_debug_print("op_median::apply(), dim = 0");
00135
00136 arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
00137
00138 out.set_size(1, X_n_cols);
00139
00140 std::vector<eT> tmp_vec(X_n_rows);
00141
00142 for(uword col=0; col<X_n_cols; ++col)
00143 {
00144 const eT* colmem = X.colptr(col);
00145
00146 for(uword row=0; row<X_n_rows; ++row)
00147 {
00148 tmp_vec[row] = colmem[row];
00149 }
00150
00151 out[col] = op_median::direct_median(tmp_vec);
00152 }
00153 }
00154 else
00155 if(dim == 1)
00156 {
00157 arma_extra_debug_print("op_median::apply(), dim = 1");
00158
00159 arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
00160
00161 out.set_size(X_n_rows, 1);
00162
00163 std::vector<eT> tmp_vec(X_n_cols);
00164
00165 for(uword row=0; row<X_n_rows; ++row)
00166 {
00167 for(uword col=0; col<X_n_cols; ++col)
00168 {
00169 tmp_vec[col] = X.at(row,col);
00170 }
00171
00172 out[row] = op_median::direct_median(tmp_vec);
00173 }
00174 }
00175 }
00176
00177
00178
00179 template<typename T>
00180 arma_inline
00181 std::complex<T>
00182 op_median::robust_mean(const std::complex<T>& A, const std::complex<T>& B)
00183 {
00184 return A + (B - A)/T(2);
00185 }
00186
00187
00188
00189 template<typename T>
00190 inline
00191 void
00192 op_median::direct_cx_median_index
00193 (
00194 uword& out_index1,
00195 uword& out_index2,
00196 std::vector< arma_cx_median_packet<T> >& X
00197 )
00198 {
00199 arma_extra_debug_sigprint();
00200
00201 const uword n_elem = X.size();
00202 const uword half = n_elem/2;
00203
00204 std::sort(X.begin(), X.end());
00205
00206 if((n_elem % 2) == 0)
00207 {
00208 out_index1 = X[half-1].index;
00209 out_index2 = X[half ].index;
00210 }
00211 else
00212 {
00213 out_index1 = X[half].index;
00214 out_index2 = out_index1;
00215 }
00216 }
00217
00218
00219
00220 template<typename T>
00221 inline
00222 void
00223 op_median::direct_cx_median_index
00224 (
00225 uword& out_index1,
00226 uword& out_index2,
00227 const std::complex<T>* X,
00228 const uword n_elem
00229 )
00230 {
00231 arma_extra_debug_sigprint();
00232
00233 std::vector< arma_cx_median_packet<T> > tmp(n_elem);
00234
00235 for(uword i=0; i<n_elem; ++i)
00236 {
00237 tmp[i].val = std::abs(X[i]);
00238 tmp[i].index = i;
00239 }
00240
00241 op_median::direct_cx_median_index(out_index1, out_index2, tmp);
00242 }
00243
00244
00245
00246 template<typename T>
00247 inline
00248 void
00249 op_median::direct_cx_median_index
00250 (
00251 uword& out_index1,
00252 uword& out_index2,
00253 const subview< std::complex<T> >&X
00254 )
00255 {
00256 arma_extra_debug_sigprint();
00257
00258 const uword n_elem = X.n_elem;
00259
00260 std::vector< arma_cx_median_packet<T> > tmp(n_elem);
00261
00262 for(uword i=0; i<n_elem; ++i)
00263 {
00264 tmp[i].val = std::abs(X[i]);
00265 tmp[i].index = i;
00266 }
00267
00268 op_median::direct_cx_median_index(out_index1, out_index2, tmp);
00269 }
00270
00271
00272
00273 template<typename T>
00274 inline
00275 void
00276 op_median::direct_cx_median_index
00277 (
00278 uword& out_index1,
00279 uword& out_index2,
00280 const diagview< std::complex<T> >&X
00281 )
00282 {
00283 arma_extra_debug_sigprint();
00284
00285 const uword n_elem = X.n_elem;
00286
00287 std::vector< arma_cx_median_packet<T> > tmp(n_elem);
00288
00289 for(uword i=0; i<n_elem; ++i)
00290 {
00291 tmp[i].val = std::abs(X[i]);
00292 tmp[i].index = i;
00293 }
00294
00295 op_median::direct_cx_median_index(out_index1, out_index2, tmp);
00296 }
00297
00298
00299
00301 template<typename T, typename T1>
00302 inline
00303 void
00304 op_median::apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in)
00305 {
00306 arma_extra_debug_sigprint();
00307
00308 typedef typename std::complex<T> eT;
00309
00310 arma_type_check(( is_same_type<eT, typename T1::elem_type>::value == false ));
00311
00312 const unwrap_check<T1> tmp(in.m, out);
00313 const Mat<eT>& X = tmp.M;
00314
00315 const uword X_n_rows = X.n_rows;
00316 const uword X_n_cols = X.n_cols;
00317
00318 const uword dim = in.aux_uword_a;
00319 arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
00320
00321 if(dim == 0)
00322 {
00323 arma_extra_debug_print("op_median::apply(), dim = 0");
00324
00325 arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
00326
00327 out.set_size(1, X_n_cols);
00328
00329 std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows);
00330
00331 for(uword col=0; col<X_n_cols; ++col)
00332 {
00333 const eT* colmem = X.colptr(col);
00334
00335 for(uword row=0; row<X_n_rows; ++row)
00336 {
00337 tmp_vec[row].val = std::abs(colmem[row]);
00338 tmp_vec[row].index = row;
00339 }
00340
00341 uword index1;
00342 uword index2;
00343 op_median::direct_cx_median_index(index1, index2, tmp_vec);
00344
00345 out[col] = op_median::robust_mean(colmem[index1], colmem[index2]);
00346 }
00347 }
00348 else
00349 if(dim == 1)
00350 {
00351 arma_extra_debug_print("op_median::apply(), dim = 1");
00352
00353 arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
00354
00355 out.set_size(X_n_rows, 1);
00356
00357 std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols);
00358
00359 for(uword row=0; row<X_n_rows; ++row)
00360 {
00361 for(uword col=0; col<X_n_cols; ++col)
00362 {
00363 tmp_vec[col].val = std::abs(X.at(row,col));
00364 tmp_vec[row].index = col;
00365 }
00366
00367 uword index1;
00368 uword index2;
00369 op_median::direct_cx_median_index(index1, index2, tmp_vec);
00370
00371 out[row] = op_median::robust_mean( X.at(row,index1), X.at(row,index2) );
00372 }
00373 }
00374 }
00375
00376
00377
00379