Mercurial > hg > segmenter-vamp-plugin
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 |