$search
00001 // Copyright (C) 2009-2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2009-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 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) // in each column 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) // in each row 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) // in each column 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) // in each row 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