comparison armadillo-2.4.4/include/armadillo_bits/op_median_meat.hpp @ 0:8b6102e2a9b0

Armadillo Library
author maxzanoni76 <max.zanoni@eecs.qmul.ac.uk>
date Wed, 11 Apr 2012 09:27:06 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:8b6102e2a9b0
1 // Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
2 // Copyright (C) 2009-2011 Conrad Sanderson
3 //
4 // This file is part of the Armadillo C++ library.
5 // It is provided without any warranty of fitness
6 // for any purpose. You can redistribute this file
7 // and/or modify it under the terms of the GNU
8 // Lesser General Public License (LGPL) as published
9 // by the Free Software Foundation, either version 3
10 // of the License or (at your option) any later version.
11 // (see http://www.opensource.org/licenses for more info)
12
13
14 //! \addtogroup op_median
15 //! @{
16
17
18
19 template<typename eT>
20 arma_inline
21 eT
22 op_median::robust_mean(const eT A, const eT B)
23 {
24 return A + (B - A)/eT(2);
25 }
26
27
28
29 //! find the median value of a std::vector (contents is modified)
30 template<typename eT>
31 inline
32 eT
33 op_median::direct_median(std::vector<eT>& X)
34 {
35 arma_extra_debug_sigprint();
36
37 const uword n_elem = X.size();
38 const uword half = n_elem/2;
39
40 std::sort(X.begin(), X.end());
41
42 if((n_elem % 2) == 0)
43 {
44 return op_median::robust_mean(X[half-1], X[half]);
45 }
46 else
47 {
48 return X[half];
49 }
50 }
51
52
53
54 template<typename eT>
55 inline
56 eT
57 op_median::direct_median(const eT* X, const uword n_elem)
58 {
59 arma_extra_debug_sigprint();
60
61 std::vector<eT> tmp(X, X+n_elem);
62
63 return op_median::direct_median(tmp);
64 }
65
66
67
68 template<typename eT>
69 inline
70 eT
71 op_median::direct_median(const subview<eT>& X)
72 {
73 arma_extra_debug_sigprint();
74
75 const uword X_n_elem = X.n_elem;
76
77 std::vector<eT> tmp(X_n_elem);
78
79 for(uword i=0; i<X_n_elem; ++i)
80 {
81 tmp[i] = X[i];
82 }
83
84 return op_median::direct_median(tmp);
85 }
86
87
88
89 template<typename eT>
90 inline
91 eT
92 op_median::direct_median(const diagview<eT>& X)
93 {
94 arma_extra_debug_sigprint();
95
96 const uword X_n_elem = X.n_elem;
97
98 std::vector<eT> tmp(X_n_elem);
99
100 for(uword i=0; i<X_n_elem; ++i)
101 {
102 tmp[i] = X[i];
103 }
104
105 return op_median::direct_median(tmp);
106 }
107
108
109
110 //! \brief
111 //! For each row or for each column, find the median value.
112 //! The result is stored in a dense matrix that has either one column or one row.
113 //! The dimension, for which the medians are found, is set via the median() function.
114 template<typename T1>
115 inline
116 void
117 op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
118 {
119 arma_extra_debug_sigprint();
120
121 typedef typename T1::elem_type eT;
122
123 const unwrap_check<T1> tmp(in.m, out);
124 const Mat<eT>& X = tmp.M;
125
126 const uword X_n_rows = X.n_rows;
127 const uword X_n_cols = X.n_cols;
128
129 const uword dim = in.aux_uword_a;
130 arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
131
132 if(dim == 0) // in each column
133 {
134 arma_extra_debug_print("op_median::apply(), dim = 0");
135
136 arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
137
138 out.set_size(1, X_n_cols);
139
140 std::vector<eT> tmp_vec(X_n_rows);
141
142 for(uword col=0; col<X_n_cols; ++col)
143 {
144 const eT* colmem = X.colptr(col);
145
146 for(uword row=0; row<X_n_rows; ++row)
147 {
148 tmp_vec[row] = colmem[row];
149 }
150
151 out[col] = op_median::direct_median(tmp_vec);
152 }
153 }
154 else
155 if(dim == 1) // in each row
156 {
157 arma_extra_debug_print("op_median::apply(), dim = 1");
158
159 arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
160
161 out.set_size(X_n_rows, 1);
162
163 std::vector<eT> tmp_vec(X_n_cols);
164
165 for(uword row=0; row<X_n_rows; ++row)
166 {
167 for(uword col=0; col<X_n_cols; ++col)
168 {
169 tmp_vec[col] = X.at(row,col);
170 }
171
172 out[row] = op_median::direct_median(tmp_vec);
173 }
174 }
175 }
176
177
178
179 template<typename T>
180 arma_inline
181 std::complex<T>
182 op_median::robust_mean(const std::complex<T>& A, const std::complex<T>& B)
183 {
184 return A + (B - A)/T(2);
185 }
186
187
188
189 template<typename T>
190 inline
191 void
192 op_median::direct_cx_median_index
193 (
194 uword& out_index1,
195 uword& out_index2,
196 std::vector< arma_cx_median_packet<T> >& X
197 )
198 {
199 arma_extra_debug_sigprint();
200
201 const uword n_elem = X.size();
202 const uword half = n_elem/2;
203
204 std::sort(X.begin(), X.end());
205
206 if((n_elem % 2) == 0)
207 {
208 out_index1 = X[half-1].index;
209 out_index2 = X[half ].index;
210 }
211 else
212 {
213 out_index1 = X[half].index;
214 out_index2 = out_index1;
215 }
216 }
217
218
219
220 template<typename T>
221 inline
222 void
223 op_median::direct_cx_median_index
224 (
225 uword& out_index1,
226 uword& out_index2,
227 const std::complex<T>* X,
228 const uword n_elem
229 )
230 {
231 arma_extra_debug_sigprint();
232
233 std::vector< arma_cx_median_packet<T> > tmp(n_elem);
234
235 for(uword i=0; i<n_elem; ++i)
236 {
237 tmp[i].val = std::abs(X[i]);
238 tmp[i].index = i;
239 }
240
241 op_median::direct_cx_median_index(out_index1, out_index2, tmp);
242 }
243
244
245
246 template<typename T>
247 inline
248 void
249 op_median::direct_cx_median_index
250 (
251 uword& out_index1,
252 uword& out_index2,
253 const subview< std::complex<T> >&X
254 )
255 {
256 arma_extra_debug_sigprint();
257
258 const uword n_elem = X.n_elem;
259
260 std::vector< arma_cx_median_packet<T> > tmp(n_elem);
261
262 for(uword i=0; i<n_elem; ++i)
263 {
264 tmp[i].val = std::abs(X[i]);
265 tmp[i].index = i;
266 }
267
268 op_median::direct_cx_median_index(out_index1, out_index2, tmp);
269 }
270
271
272
273 template<typename T>
274 inline
275 void
276 op_median::direct_cx_median_index
277 (
278 uword& out_index1,
279 uword& out_index2,
280 const diagview< std::complex<T> >&X
281 )
282 {
283 arma_extra_debug_sigprint();
284
285 const uword n_elem = X.n_elem;
286
287 std::vector< arma_cx_median_packet<T> > tmp(n_elem);
288
289 for(uword i=0; i<n_elem; ++i)
290 {
291 tmp[i].val = std::abs(X[i]);
292 tmp[i].index = i;
293 }
294
295 op_median::direct_cx_median_index(out_index1, out_index2, tmp);
296 }
297
298
299
300 //! Implementation for complex numbers
301 template<typename T, typename T1>
302 inline
303 void
304 op_median::apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in)
305 {
306 arma_extra_debug_sigprint();
307
308 typedef typename std::complex<T> eT;
309
310 arma_type_check(( is_same_type<eT, typename T1::elem_type>::value == false ));
311
312 const unwrap_check<T1> tmp(in.m, out);
313 const Mat<eT>& X = tmp.M;
314
315 const uword X_n_rows = X.n_rows;
316 const uword X_n_cols = X.n_cols;
317
318 const uword dim = in.aux_uword_a;
319 arma_debug_check( (dim > 1), "median(): incorrect usage. dim must be 0 or 1");
320
321 if(dim == 0) // in each column
322 {
323 arma_extra_debug_print("op_median::apply(), dim = 0");
324
325 arma_debug_check( (X_n_rows == 0), "median(): given object has zero rows" );
326
327 out.set_size(1, X_n_cols);
328
329 std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_rows);
330
331 for(uword col=0; col<X_n_cols; ++col)
332 {
333 const eT* colmem = X.colptr(col);
334
335 for(uword row=0; row<X_n_rows; ++row)
336 {
337 tmp_vec[row].val = std::abs(colmem[row]);
338 tmp_vec[row].index = row;
339 }
340
341 uword index1;
342 uword index2;
343 op_median::direct_cx_median_index(index1, index2, tmp_vec);
344
345 out[col] = op_median::robust_mean(colmem[index1], colmem[index2]);
346 }
347 }
348 else
349 if(dim == 1) // in each row
350 {
351 arma_extra_debug_print("op_median::apply(), dim = 1");
352
353 arma_debug_check( (X_n_cols == 0), "median(): given object has zero columns" );
354
355 out.set_size(X_n_rows, 1);
356
357 std::vector< arma_cx_median_packet<T> > tmp_vec(X_n_cols);
358
359 for(uword row=0; row<X_n_rows; ++row)
360 {
361 for(uword col=0; col<X_n_cols; ++col)
362 {
363 tmp_vec[col].val = std::abs(X.at(row,col));
364 tmp_vec[row].index = col;
365 }
366
367 uword index1;
368 uword index2;
369 op_median::direct_cx_median_index(index1, index2, tmp_vec);
370
371 out[row] = op_median::robust_mean( X.at(row,index1), X.at(row,index2) );
372 }
373 }
374 }
375
376
377
378 //! @}
379