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