Mercurial > hg > segmenter-vamp-plugin
comparison armadillo-3.900.4/include/armadillo_bits/spop_var_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) 2012 Ryan Curtin | |
2 // Copyright (C) 2012 Conrad Sanderson | |
3 // | |
4 // This Source Code Form is subject to the terms of the Mozilla Public | |
5 // License, v. 2.0. If a copy of the MPL was not distributed with this | |
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
7 | |
8 | |
9 //! \addtogroup spop_var | |
10 //! @{ | |
11 | |
12 | |
13 | |
14 template<typename T1> | |
15 inline | |
16 void | |
17 spop_var::apply(SpMat<typename T1::pod_type>& out, const mtSpOp<typename T1::pod_type, T1, spop_var>& in) | |
18 { | |
19 arma_extra_debug_sigprint(); | |
20 | |
21 //typedef typename T1::elem_type in_eT; | |
22 typedef typename T1::pod_type out_eT; | |
23 | |
24 const uword norm_type = in.aux_uword_a; | |
25 const uword dim = in.aux_uword_b; | |
26 | |
27 arma_debug_check((norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1"); | |
28 arma_debug_check((dim > 1), "var(): incorrect usage. dim must be 0 or 1"); | |
29 | |
30 SpProxy<T1> p(in.m); | |
31 | |
32 if(p.is_alias(out) == false) | |
33 { | |
34 spop_var::apply_noalias(out, p, norm_type, dim); | |
35 } | |
36 else | |
37 { | |
38 SpMat<out_eT> tmp; | |
39 | |
40 spop_var::apply_noalias(tmp, p, norm_type, dim); | |
41 | |
42 out.steal_mem(tmp); | |
43 } | |
44 } | |
45 | |
46 | |
47 | |
48 template<typename T1> | |
49 inline | |
50 void | |
51 spop_var::apply_noalias | |
52 ( | |
53 SpMat<typename T1::pod_type>& out_ref, | |
54 const SpProxy<T1>& p, | |
55 const uword norm_type, | |
56 const uword dim | |
57 ) | |
58 { | |
59 arma_extra_debug_sigprint(); | |
60 | |
61 typedef typename T1::elem_type in_eT; | |
62 //typedef typename T1::pod_type out_eT; | |
63 | |
64 const uword p_n_rows = p.get_n_rows(); | |
65 const uword p_n_cols = p.get_n_cols(); | |
66 | |
67 if(dim == 0) | |
68 { | |
69 arma_extra_debug_print("spop_var::apply(), dim = 0"); | |
70 | |
71 arma_debug_check((p_n_rows == 0), "var(): given object has zero rows"); | |
72 | |
73 out_ref.set_size(1, p_n_cols); | |
74 | |
75 for(uword col = 0; col < p_n_cols; ++col) | |
76 { | |
77 if(SpProxy<T1>::must_use_iterator == true) | |
78 { | |
79 // We must use an iterator; we can't access memory directly. | |
80 typename SpProxy<T1>::const_iterator_type it = p.begin_col(col); | |
81 typename SpProxy<T1>::const_iterator_type end = p.begin_col(col + 1); | |
82 | |
83 const uword n_zero = p.get_n_rows() - (end.pos() - it.pos()); | |
84 | |
85 // in_eT is used just to get the specialization right (complex / noncomplex) | |
86 out_ref.at(col) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0)); | |
87 } | |
88 else | |
89 { | |
90 // We can use direct memory access to calculate the variance. | |
91 out_ref.at(col) = spop_var::direct_var | |
92 ( | |
93 &p.get_values()[p.get_col_ptrs()[col]], | |
94 p.get_col_ptrs()[col + 1] - p.get_col_ptrs()[col], | |
95 p.get_n_rows(), | |
96 norm_type | |
97 ); | |
98 } | |
99 } | |
100 } | |
101 else if(dim == 1) | |
102 { | |
103 arma_extra_debug_print("spop_var::apply_noalias(), dim = 1"); | |
104 | |
105 arma_debug_check((p_n_cols == 0), "var(): given object has zero columns"); | |
106 | |
107 out_ref.set_size(p_n_rows, 1); | |
108 | |
109 for(uword row = 0; row < p_n_rows; ++row) | |
110 { | |
111 // We have to use an iterator here regardless of whether or not we can | |
112 // directly access memory. | |
113 typename SpProxy<T1>::const_row_iterator_type it = p.begin_row(row); | |
114 typename SpProxy<T1>::const_row_iterator_type end = p.end_row(row); | |
115 | |
116 const uword n_zero = p.get_n_cols() - (end.pos() - it.pos()); | |
117 | |
118 out_ref.at(row) = spop_var::iterator_var(it, end, n_zero, norm_type, in_eT(0)); | |
119 } | |
120 } | |
121 } | |
122 | |
123 | |
124 | |
125 template<typename T1> | |
126 inline | |
127 typename T1::pod_type | |
128 spop_var::var_vec | |
129 ( | |
130 const T1& X, | |
131 const uword norm_type | |
132 ) | |
133 { | |
134 arma_extra_debug_sigprint(); | |
135 | |
136 arma_debug_check((norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1."); | |
137 | |
138 // conditionally unwrap it into a temporary and then directly operate. | |
139 | |
140 const unwrap_spmat<T1> tmp(X); | |
141 | |
142 return direct_var(tmp.M.values, tmp.M.n_nonzero, tmp.M.n_elem, norm_type); | |
143 } | |
144 | |
145 | |
146 | |
147 template<typename eT> | |
148 inline | |
149 eT | |
150 spop_var::direct_var | |
151 ( | |
152 const eT* const X, | |
153 const uword length, | |
154 const uword N, | |
155 const uword norm_type | |
156 ) | |
157 { | |
158 arma_extra_debug_sigprint(); | |
159 | |
160 if(length >= 2 && N >= 2) | |
161 { | |
162 const eT acc1 = spop_mean::direct_mean(X, length, N); | |
163 | |
164 eT acc2 = eT(0); | |
165 eT acc3 = eT(0); | |
166 | |
167 uword i, j; | |
168 | |
169 for(i = 0, j = 1; j < length; i += 2, j += 2) | |
170 { | |
171 const eT Xi = X[i]; | |
172 const eT Xj = X[j]; | |
173 | |
174 const eT tmpi = acc1 - Xi; | |
175 const eT tmpj = acc1 - Xj; | |
176 | |
177 acc2 += tmpi * tmpi + tmpj * tmpj; | |
178 acc3 += tmpi + tmpj; | |
179 } | |
180 | |
181 if(i < length) | |
182 { | |
183 const eT Xi = X[i]; | |
184 | |
185 const eT tmpi = acc1 - Xi; | |
186 | |
187 acc2 += tmpi * tmpi; | |
188 acc3 += tmpi; | |
189 } | |
190 | |
191 // Now add in all zero elements. | |
192 acc2 += (N - length) * (acc1 * acc1); | |
193 acc3 += (N - length) * acc1; | |
194 | |
195 const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N); | |
196 const eT var_val = (acc2 - (acc3 * acc3) / eT(N)) / norm_val; | |
197 | |
198 return var_val; | |
199 } | |
200 else if(length == 1 && N > 1) // if N == 1, then variance is zero. | |
201 { | |
202 const eT mean = X[0] / eT(N); | |
203 const eT val = mean - X[0]; | |
204 | |
205 const eT acc2 = (val * val) + (N - length) * (mean * mean); | |
206 const eT acc3 = val + (N - length) * mean; | |
207 | |
208 const eT norm_val = (norm_type == 0) ? eT(N - 1) : eT(N); | |
209 const eT var_val = (acc2 - (acc3 * acc3) / eT(N)) / norm_val; | |
210 | |
211 return var_val; | |
212 } | |
213 else | |
214 { | |
215 return eT(0); | |
216 } | |
217 } | |
218 | |
219 | |
220 | |
221 template<typename T> | |
222 inline | |
223 T | |
224 spop_var::direct_var | |
225 ( | |
226 const std::complex<T>* const X, | |
227 const uword length, | |
228 const uword N, | |
229 const uword norm_type | |
230 ) | |
231 { | |
232 arma_extra_debug_sigprint(); | |
233 | |
234 typedef typename std::complex<T> eT; | |
235 | |
236 if(length >= 2 && N >= 2) | |
237 { | |
238 const eT acc1 = spop_mean::direct_mean(X, length, N); | |
239 | |
240 T acc2 = T(0); | |
241 eT acc3 = eT(0); | |
242 | |
243 for (uword i = 0; i < length; ++i) | |
244 { | |
245 const eT tmp = acc1 - X[i]; | |
246 | |
247 acc2 += std::norm(tmp); | |
248 acc3 += tmp; | |
249 } | |
250 | |
251 // Add zero elements to sums | |
252 acc2 += std::norm(acc1) * T(N - length); | |
253 acc3 += acc1 * T(N - length); | |
254 | |
255 const T norm_val = (norm_type == 0) ? T(N - 1) : T(N); | |
256 const T var_val = (acc2 - std::norm(acc3) / T(N)) / norm_val; | |
257 | |
258 return var_val; | |
259 } | |
260 else if(length == 1 && N > 1) // if N == 1, then variance is zero. | |
261 { | |
262 const eT mean = X[0] / T(N); | |
263 const eT val = mean - X[0]; | |
264 | |
265 const T acc2 = std::norm(val) + (N - length) * std::norm(mean); | |
266 const eT acc3 = val + T(N - length) * mean; | |
267 | |
268 const T norm_val = (norm_type == 0) ? T(N - 1) : T(N); | |
269 const T var_val = (acc2 - std::norm(acc3) / T(N)) / norm_val; | |
270 | |
271 return var_val; | |
272 } | |
273 else | |
274 { | |
275 return T(0); // All elements are zero | |
276 } | |
277 } | |
278 | |
279 | |
280 | |
281 template<typename T1, typename eT> | |
282 inline | |
283 eT | |
284 spop_var::iterator_var | |
285 ( | |
286 T1& it, | |
287 const T1& end, | |
288 const uword n_zero, | |
289 const uword norm_type, | |
290 const eT junk1, | |
291 const typename arma_not_cx<eT>::result* junk2 | |
292 ) | |
293 { | |
294 arma_extra_debug_sigprint(); | |
295 arma_ignore(junk1); | |
296 arma_ignore(junk2); | |
297 | |
298 T1 new_it(it); // for mean | |
299 // T1 backup_it(it); // in case we have to call robust iterator_var | |
300 eT mean = spop_mean::iterator_mean(new_it, end, n_zero, eT(0)); | |
301 | |
302 eT acc2 = eT(0); | |
303 eT acc3 = eT(0); | |
304 | |
305 const uword it_begin_pos = it.pos(); | |
306 | |
307 while (it != end) | |
308 { | |
309 const eT tmp = mean - (*it); | |
310 | |
311 acc2 += (tmp * tmp); | |
312 acc3 += (tmp); | |
313 | |
314 ++it; | |
315 } | |
316 | |
317 const uword n_nonzero = (it.pos() - it_begin_pos); | |
318 if (n_nonzero == 0) | |
319 { | |
320 return eT(0); | |
321 } | |
322 | |
323 if (n_nonzero + n_zero == 1) | |
324 { | |
325 return eT(0); // only one element | |
326 } | |
327 | |
328 // Add in entries for zeros. | |
329 acc2 += eT(n_zero) * (mean * mean); | |
330 acc3 += eT(n_zero) * mean; | |
331 | |
332 const eT norm_val = (norm_type == 0) ? eT(n_zero + n_nonzero - 1) : eT(n_zero + n_nonzero); | |
333 const eT var_val = (acc2 - (acc3 * acc3) / eT(n_nonzero + n_zero)) / norm_val; | |
334 | |
335 return var_val; | |
336 } | |
337 | |
338 | |
339 | |
340 template<typename T1, typename eT> | |
341 inline | |
342 typename get_pod_type<eT>::result | |
343 spop_var::iterator_var | |
344 ( | |
345 T1& it, | |
346 const T1& end, | |
347 const uword n_zero, | |
348 const uword norm_type, | |
349 const eT junk1, | |
350 const typename arma_cx_only<eT>::result* junk2 | |
351 ) | |
352 { | |
353 arma_extra_debug_sigprint(); | |
354 arma_ignore(junk1); | |
355 arma_ignore(junk2); | |
356 | |
357 typedef typename get_pod_type<eT>::result T; | |
358 | |
359 T1 new_it(it); // for mean | |
360 // T1 backup_it(it); // in case we have to call robust iterator_var | |
361 eT mean = spop_mean::iterator_mean(new_it, end, n_zero, eT(0)); | |
362 | |
363 T acc2 = T(0); | |
364 eT acc3 = eT(0); | |
365 | |
366 const uword it_begin_pos = it.pos(); | |
367 | |
368 while (it != end) | |
369 { | |
370 eT tmp = mean - (*it); | |
371 | |
372 acc2 += std::norm(tmp); | |
373 acc3 += (tmp); | |
374 | |
375 ++it; | |
376 } | |
377 | |
378 const uword n_nonzero = (it.pos() - it_begin_pos); | |
379 if (n_nonzero == 0) | |
380 { | |
381 return T(0); | |
382 } | |
383 | |
384 if (n_nonzero + n_zero == 1) | |
385 { | |
386 return T(0); // only one element | |
387 } | |
388 | |
389 // Add in entries for zero elements. | |
390 acc2 += T(n_zero) * std::norm(mean); | |
391 acc3 += T(n_zero) * mean; | |
392 | |
393 const T norm_val = (norm_type == 0) ? T(n_zero + n_nonzero - 1) : T(n_zero + n_nonzero); | |
394 const T var_val = (acc2 - std::norm(acc3) / T(n_nonzero + n_zero)) / norm_val; | |
395 | |
396 return var_val; | |
397 } | |
398 | |
399 | |
400 | |
401 //! @} |