Mercurial > hg > segmenter-vamp-plugin
comparison armadillo-3.900.4/include/armadillo_bits/op_median_meat.hpp @ 49:1ec0e2823891
Switch to using subrepo copies of qm-dsp, nnls-chroma, vamp-plugin-sdk; update Armadillo version; assume build without external BLAS/LAPACK
author | Chris Cannam |
---|---|
date | Thu, 13 Jun 2013 10:25:24 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
48:69251e11a913 | 49:1ec0e2823891 |
---|---|
1 // Copyright (C) 2009-2013 NICTA (www.nicta.com.au) | |
2 // Copyright (C) 2009-2013 Conrad Sanderson | |
3 // Copyright (C) 2013 Ruslan Shestopalyuk | |
4 // | |
5 // This Source Code Form is subject to the terms of the Mozilla Public | |
6 // License, v. 2.0. If a copy of the MPL was not distributed with this | |
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
8 | |
9 | |
10 //! \addtogroup op_median | |
11 //! @{ | |
12 | |
13 | |
14 | |
15 //! \brief | |
16 //! For each row or for each column, find the median value. | |
17 //! The result is stored in a dense matrix that has either one column or one row. | |
18 //! The dimension, for which the medians are found, is set via the median() function. | |
19 template<typename T1> | |
20 inline | |
21 void | |
22 op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in) | |
23 { | |
24 arma_extra_debug_sigprint(); | |
25 | |
26 typedef typename T1::elem_type eT; | |
27 | |
28 const uword dim = in.aux_uword_a; | |
29 arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1"); | |
30 | |
31 const Proxy<T1> P(in.m); | |
32 | |
33 typedef typename Proxy<T1>::stored_type P_stored_type; | |
34 | |
35 const bool is_alias = P.is_alias(out); | |
36 | |
37 if( (is_Mat<P_stored_type>::value == true) || is_alias ) | |
38 { | |
39 const unwrap_check<P_stored_type> tmp(P.Q, is_alias); | |
40 | |
41 const typename unwrap_check<P_stored_type>::stored_type& X = tmp.M; | |
42 | |
43 const uword X_n_rows = X.n_rows; | |
44 const uword X_n_cols = X.n_cols; | |
45 | |
46 if(dim == 0) // in each column | |
47 { | |
48 arma_extra_debug_print("op_median::apply(), dim = 0"); | |
49 | |
50 arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" ); | |
51 | |
52 out.set_size(1, X_n_cols); | |
53 | |
54 std::vector<eT> tmp_vec(X_n_rows); | |
55 | |
56 for(uword col=0; col < X_n_cols; ++col) | |
57 { | |
58 arrayops::copy( &(tmp_vec[0]), X.colptr(col), X_n_rows ); | |
59 | |
60 out[col] = op_median::direct_median(tmp_vec); | |
61 } | |
62 } | |
63 else // in each row | |
64 { | |
65 arma_extra_debug_print("op_median::apply(), dim = 1"); | |
66 | |
67 arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" ); | |
68 | |
69 out.set_size(X_n_rows, 1); | |
70 | |
71 std::vector<eT> tmp_vec(X_n_cols); | |
72 | |
73 for(uword row=0; row < X_n_rows; ++row) | |
74 { | |
75 for(uword col=0; col < X_n_cols; ++col) { tmp_vec[col] = X.at(row,col); } | |
76 | |
77 out[row] = op_median::direct_median(tmp_vec); | |
78 } | |
79 } | |
80 } | |
81 else | |
82 { | |
83 const uword P_n_rows = P.get_n_rows(); | |
84 const uword P_n_cols = P.get_n_cols(); | |
85 | |
86 if(dim == 0) // in each column | |
87 { | |
88 arma_extra_debug_print("op_median::apply(), dim = 0"); | |
89 | |
90 arma_debug_check( (P_n_rows == 0), "median(): given object has zero rows" ); | |
91 | |
92 out.set_size(1, P_n_cols); | |
93 | |
94 std::vector<eT> tmp_vec(P_n_rows); | |
95 | |
96 for(uword col=0; col < P_n_cols; ++col) | |
97 { | |
98 for(uword row=0; row < P_n_rows; ++row) { tmp_vec[row] = P.at(row,col); } | |
99 | |
100 out[col] = op_median::direct_median(tmp_vec); | |
101 } | |
102 } | |
103 else // in each row | |
104 { | |
105 arma_extra_debug_print("op_median::apply(), dim = 1"); | |
106 | |
107 arma_debug_check( (P_n_cols == 0), "median(): given object has zero columns" ); | |
108 | |
109 out.set_size(P_n_rows, 1); | |
110 | |
111 std::vector<eT> tmp_vec(P_n_cols); | |
112 | |
113 for(uword row=0; row < P_n_rows; ++row) | |
114 { | |
115 for(uword col=0; col < P_n_cols; ++col) { tmp_vec[col] = P.at(row,col); } | |
116 | |
117 out[row] = op_median::direct_median(tmp_vec); | |
118 } | |
119 } | |
120 } | |
121 } | |
122 | |
123 | |
124 | |
125 //! Implementation for complex numbers | |
126 template<typename T, typename T1> | |
127 inline | |
128 void | |
129 op_median::apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in) | |
130 { | |
131 arma_extra_debug_sigprint(); | |
132 | |
133 typedef typename std::complex<T> eT; | |
134 | |
135 arma_type_check(( is_same_type<eT, typename T1::elem_type>::value == false )); | |
136 | |
137 const unwrap_check<T1> tmp(in.m, out); | |
138 const Mat<eT>& X = tmp.M; | |
139 | |
140 const uword X_n_rows = X.n_rows; | |
141 const uword X_n_cols = X.n_cols; | |
142 | |
143 const uword dim = in.aux_uword_a; | |
144 arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1"); | |
145 | |
146 if(dim == 0) // in each column | |
147 { | |
148 arma_extra_debug_print("op_median::apply(), dim = 0"); | |
149 | |
150 arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" ); | |
151 | |
152 out.set_size(1, X_n_cols); | |
153 | |
154 std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows); | |
155 | |
156 for(uword col=0; col<X_n_cols; ++col) | |
157 { | |
158 const eT* colmem = X.colptr(col); | |
159 | |
160 for(uword row=0; row<X_n_rows; ++row) | |
161 { | |
162 tmp_vec[row].val = std::abs(colmem[row]); | |
163 tmp_vec[row].index = row; | |
164 } | |
165 | |
166 uword index1; | |
167 uword index2; | |
168 op_median::direct_cx_median_index(index1, index2, tmp_vec); | |
169 | |
170 out[col] = op_mean::robust_mean(colmem[index1], colmem[index2]); | |
171 } | |
172 } | |
173 else | |
174 if(dim == 1) // in each row | |
175 { | |
176 arma_extra_debug_print("op_median::apply(), dim = 1"); | |
177 | |
178 arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" ); | |
179 | |
180 out.set_size(X_n_rows, 1); | |
181 | |
182 std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols); | |
183 | |
184 for(uword row=0; row<X_n_rows; ++row) | |
185 { | |
186 for(uword col=0; col<X_n_cols; ++col) | |
187 { | |
188 tmp_vec[col].val = std::abs(X.at(row,col)); | |
189 tmp_vec[col].index = col; | |
190 } | |
191 | |
192 uword index1; | |
193 uword index2; | |
194 op_median::direct_cx_median_index(index1, index2, tmp_vec); | |
195 | |
196 out[row] = op_mean::robust_mean( X.at(row,index1), X.at(row,index2) ); | |
197 } | |
198 } | |
199 } | |
200 | |
201 | |
202 | |
203 template<typename T1> | |
204 inline | |
205 typename T1::elem_type | |
206 op_median::median_vec | |
207 ( | |
208 const T1& X, | |
209 const typename arma_not_cx<typename T1::elem_type>::result* junk | |
210 ) | |
211 { | |
212 arma_extra_debug_sigprint(); | |
213 arma_ignore(junk); | |
214 | |
215 typedef typename T1::elem_type eT; | |
216 | |
217 typedef typename Proxy<T1>::stored_type P_stored_type; | |
218 | |
219 const Proxy<T1> P(X); | |
220 | |
221 const uword n_elem = P.get_n_elem(); | |
222 | |
223 arma_debug_check( (n_elem == 0), "median(): given object has no elements" ); | |
224 | |
225 std::vector<eT> tmp_vec(n_elem); | |
226 | |
227 if(is_Mat<P_stored_type>::value == true) | |
228 { | |
229 const unwrap<P_stored_type> tmp(P.Q); | |
230 | |
231 const typename unwrap_check<P_stored_type>::stored_type& Y = tmp.M; | |
232 | |
233 arrayops::copy( &(tmp_vec[0]), Y.memptr(), n_elem ); | |
234 } | |
235 else | |
236 { | |
237 if(Proxy<T1>::prefer_at_accessor == false) | |
238 { | |
239 typedef typename Proxy<T1>::ea_type ea_type; | |
240 | |
241 ea_type A = P.get_ea(); | |
242 | |
243 for(uword i=0; i<n_elem; ++i) { tmp_vec[i] = A[i]; } | |
244 } | |
245 else | |
246 { | |
247 const uword n_rows = P.get_n_rows(); | |
248 const uword n_cols = P.get_n_cols(); | |
249 | |
250 if(n_cols == 1) | |
251 { | |
252 for(uword row=0; row < n_rows; ++row) { tmp_vec[row] = P.at(row,0); } | |
253 } | |
254 else | |
255 if(n_rows == 1) | |
256 { | |
257 for(uword col=0; col < n_cols; ++col) { tmp_vec[col] = P.at(0,col); } | |
258 } | |
259 else | |
260 { | |
261 arma_stop("op_median::median_vec(): expected a vector" ); | |
262 } | |
263 } | |
264 } | |
265 | |
266 return op_median::direct_median(tmp_vec); | |
267 } | |
268 | |
269 | |
270 | |
271 template<typename T1> | |
272 inline | |
273 typename T1::elem_type | |
274 op_median::median_vec | |
275 ( | |
276 const T1& X, | |
277 const typename arma_cx_only<typename T1::elem_type>::result* junk | |
278 ) | |
279 { | |
280 arma_extra_debug_sigprint(); | |
281 arma_ignore(junk); | |
282 | |
283 typedef typename T1::elem_type eT; | |
284 typedef typename T1::pod_type T; | |
285 | |
286 const Proxy<T1> P(X); | |
287 | |
288 const uword n_elem = P.get_n_elem(); | |
289 | |
290 arma_debug_check( (n_elem == 0), "median(): given object has no elements" ); | |
291 | |
292 std::vector< arma_cx_median_packet<T> > tmp_vec(n_elem); | |
293 | |
294 if(Proxy<T1>::prefer_at_accessor == false) | |
295 { | |
296 typedef typename Proxy<T1>::ea_type ea_type; | |
297 | |
298 ea_type A = P.get_ea(); | |
299 | |
300 for(uword i=0; i<n_elem; ++i) | |
301 { | |
302 tmp_vec[i].val = std::abs( A[i] ); | |
303 tmp_vec[i].index = i; | |
304 } | |
305 | |
306 uword index1; | |
307 uword index2; | |
308 op_median::direct_cx_median_index(index1, index2, tmp_vec); | |
309 | |
310 return op_mean::robust_mean( A[index1], A[index2] ); | |
311 } | |
312 else | |
313 { | |
314 const uword n_rows = P.get_n_rows(); | |
315 const uword n_cols = P.get_n_cols(); | |
316 | |
317 if(n_cols == 1) | |
318 { | |
319 for(uword row=0; row < n_rows; ++row) | |
320 { | |
321 tmp_vec[row].val = std::abs( P.at(row,0) ); | |
322 tmp_vec[row].index = row; | |
323 } | |
324 | |
325 uword index1; | |
326 uword index2; | |
327 op_median::direct_cx_median_index(index1, index2, tmp_vec); | |
328 | |
329 return op_mean::robust_mean( P.at(index1,0), P.at(index2,0) ); | |
330 } | |
331 else | |
332 if(n_rows == 1) | |
333 { | |
334 for(uword col=0; col < n_cols; ++col) | |
335 { | |
336 tmp_vec[col].val = std::abs( P.at(0,col) ); | |
337 tmp_vec[col].index = col; | |
338 } | |
339 | |
340 uword index1; | |
341 uword index2; | |
342 op_median::direct_cx_median_index(index1, index2, tmp_vec); | |
343 | |
344 return op_mean::robust_mean( P.at(0,index1), P.at(0,index2) ); | |
345 } | |
346 else | |
347 { | |
348 arma_stop("op_median::median_vec(): expected a vector" ); | |
349 | |
350 return eT(0); | |
351 } | |
352 } | |
353 } | |
354 | |
355 | |
356 | |
357 //! find the median value of a std::vector (contents is modified) | |
358 template<typename eT> | |
359 inline | |
360 eT | |
361 op_median::direct_median(std::vector<eT>& X) | |
362 { | |
363 arma_extra_debug_sigprint(); | |
364 | |
365 const uword n_elem = uword(X.size()); | |
366 const uword half = n_elem/2; | |
367 | |
368 std::nth_element(X.begin(), X.begin() + half, X.end()); | |
369 | |
370 if((n_elem % 2) == 0) | |
371 { | |
372 return op_mean::robust_mean(*(std::max_element(X.begin(), X.begin() + half)), X[half]); | |
373 } | |
374 else | |
375 { | |
376 return X[half]; | |
377 } | |
378 } | |
379 | |
380 | |
381 | |
382 template<typename T> | |
383 inline | |
384 void | |
385 op_median::direct_cx_median_index | |
386 ( | |
387 uword& out_index1, | |
388 uword& out_index2, | |
389 std::vector< arma_cx_median_packet<T> >& X | |
390 ) | |
391 { | |
392 arma_extra_debug_sigprint(); | |
393 | |
394 const uword n_elem = uword(X.size()); | |
395 const uword half = n_elem/2; | |
396 | |
397 std::nth_element(X.begin(), X.begin() + half, X.end()); | |
398 | |
399 if((n_elem % 2) == 0) | |
400 { | |
401 out_index1 = std::max_element(X.begin(), X.begin() + half)->index; | |
402 out_index2 = X[half].index; | |
403 } | |
404 else | |
405 { | |
406 out_index1 = X[half].index; | |
407 out_index2 = out_index1; | |
408 } | |
409 } | |
410 | |
411 | |
412 | |
413 //! @} | |
414 |