comparison armadillo-3.900.4/include/armadillo_bits/op_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) 2009-2012 NICTA (www.nicta.com.au)
2 // Copyright (C) 2009-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 op_var
10 //! @{
11
12
13 //! \brief
14 //! For each row or for each column, find the variance.
15 //! The result is stored in a dense matrix that has either one column or one row.
16 //! The dimension, for which the variances are found, is set via the var() function.
17 template<typename T1>
18 inline
19 void
20 op_var::apply(Mat<typename T1::pod_type>& out, const mtOp<typename T1::pod_type, T1, op_var>& in)
21 {
22 arma_extra_debug_sigprint();
23
24 typedef typename T1::elem_type in_eT;
25 typedef typename T1::pod_type out_eT;
26
27 const unwrap_check_mixed<T1> tmp(in.m, out);
28 const Mat<in_eT>& X = tmp.M;
29
30 const uword norm_type = in.aux_uword_a;
31 const uword dim = in.aux_uword_b;
32
33 arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
34 arma_debug_check( (dim > 1), "var(): incorrect usage. dim must be 0 or 1" );
35
36 const uword X_n_rows = X.n_rows;
37 const uword X_n_cols = X.n_cols;
38
39 if(dim == 0)
40 {
41 arma_extra_debug_print("op_var::apply(), dim = 0");
42
43 arma_debug_check( (X_n_rows == 0), "var(): given object has zero rows" );
44
45 out.set_size(1, X_n_cols);
46
47 out_eT* out_mem = out.memptr();
48
49 for(uword col=0; col<X_n_cols; ++col)
50 {
51 out_mem[col] = op_var::direct_var( X.colptr(col), X_n_rows, norm_type );
52 }
53 }
54 else
55 if(dim == 1)
56 {
57 arma_extra_debug_print("op_var::apply(), dim = 1");
58
59 arma_debug_check( (X_n_cols == 0), "var(): given object has zero columns" );
60
61 out.set_size(X_n_rows, 1);
62
63 podarray<in_eT> dat(X_n_cols);
64
65 in_eT* dat_mem = dat.memptr();
66 out_eT* out_mem = out.memptr();
67
68 for(uword row=0; row<X_n_rows; ++row)
69 {
70 dat.copy_row(X, row);
71
72 out_mem[row] = op_var::direct_var( dat_mem, X_n_cols, norm_type );
73 }
74 }
75 }
76
77
78
79 template<typename T1>
80 inline
81 typename T1::pod_type
82 op_var::var_vec(const Base<typename T1::elem_type, T1>& X, const uword norm_type)
83 {
84 arma_extra_debug_sigprint();
85
86 typedef typename T1::elem_type eT;
87
88 arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
89
90 const Proxy<T1> P(X.get_ref());
91
92 const podarray<eT> tmp(P);
93
94 return op_var::direct_var(tmp.memptr(), tmp.n_elem, norm_type);
95 }
96
97
98
99 template<typename eT>
100 inline
101 typename get_pod_type<eT>::result
102 op_var::var_vec(const subview_col<eT>& X, const uword norm_type)
103 {
104 arma_extra_debug_sigprint();
105
106 arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
107
108 return op_var::direct_var(X.colptr(0), X.n_rows, norm_type);
109 }
110
111
112
113
114 template<typename eT>
115 inline
116 typename get_pod_type<eT>::result
117 op_var::var_vec(const subview_row<eT>& X, const uword norm_type)
118 {
119 arma_extra_debug_sigprint();
120
121 arma_debug_check( (norm_type > 1), "var(): incorrect usage. norm_type must be 0 or 1");
122
123 const Mat<eT>& A = X.m;
124
125 const uword start_row = X.aux_row1;
126 const uword start_col = X.aux_col1;
127
128 const uword end_col_p1 = start_col + X.n_cols;
129
130 podarray<eT> tmp(X.n_elem);
131 eT* tmp_mem = tmp.memptr();
132
133 for(uword i=0, col=start_col; col < end_col_p1; ++col, ++i)
134 {
135 tmp_mem[i] = A.at(start_row, col);
136 }
137
138 return op_var::direct_var(tmp.memptr(), tmp.n_elem, norm_type);
139 }
140
141
142
143 //! find the variance of an array
144 template<typename eT>
145 inline
146 eT
147 op_var::direct_var(const eT* const X, const uword n_elem, const uword norm_type)
148 {
149 arma_extra_debug_sigprint();
150
151 if(n_elem >= 2)
152 {
153 const eT acc1 = op_mean::direct_mean(X, n_elem);
154
155 eT acc2 = eT(0);
156 eT acc3 = eT(0);
157
158 uword i,j;
159
160 for(i=0, j=1; j<n_elem; i+=2, j+=2)
161 {
162 const eT Xi = X[i];
163 const eT Xj = X[j];
164
165 const eT tmpi = acc1 - Xi;
166 const eT tmpj = acc1 - Xj;
167
168 acc2 += tmpi*tmpi + tmpj*tmpj;
169 acc3 += tmpi + tmpj;
170 }
171
172 if(i < n_elem)
173 {
174 const eT Xi = X[i];
175
176 const eT tmpi = acc1 - Xi;
177
178 acc2 += tmpi*tmpi;
179 acc3 += tmpi;
180 }
181
182 const eT norm_val = (norm_type == 0) ? eT(n_elem-1) : eT(n_elem);
183 const eT var_val = (acc2 - acc3*acc3/eT(n_elem)) / norm_val;
184
185 return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
186 }
187 else
188 {
189 return eT(0);
190 }
191 }
192
193
194
195 //! find the variance of an array (robust but slow)
196 template<typename eT>
197 inline
198 eT
199 op_var::direct_var_robust(const eT* const X, const uword n_elem, const uword norm_type)
200 {
201 arma_extra_debug_sigprint();
202
203 if(n_elem > 1)
204 {
205 eT r_mean = X[0];
206 eT r_var = eT(0);
207
208 for(uword i=1; i<n_elem; ++i)
209 {
210 const eT tmp = X[i] - r_mean;
211 const eT i_plus_1 = eT(i+1);
212
213 r_var = eT(i-1)/eT(i) * r_var + (tmp*tmp)/i_plus_1;
214
215 r_mean = r_mean + tmp/i_plus_1;
216 }
217
218 return (norm_type == 0) ? r_var : (eT(n_elem-1)/eT(n_elem)) * r_var;
219 }
220 else
221 {
222 return eT(0);
223 }
224 }
225
226
227
228 //! find the variance of an array (version for complex numbers)
229 template<typename T>
230 inline
231 T
232 op_var::direct_var(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
233 {
234 arma_extra_debug_sigprint();
235
236 typedef typename std::complex<T> eT;
237
238 if(n_elem >= 2)
239 {
240 const eT acc1 = op_mean::direct_mean(X, n_elem);
241
242 T acc2 = T(0);
243 eT acc3 = eT(0);
244
245 for(uword i=0; i<n_elem; ++i)
246 {
247 const eT tmp = acc1 - X[i];
248
249 acc2 += std::norm(tmp);
250 acc3 += tmp;
251 }
252
253 const T norm_val = (norm_type == 0) ? T(n_elem-1) : T(n_elem);
254 const T var_val = (acc2 - std::norm(acc3)/T(n_elem)) / norm_val;
255
256 return arma_isfinite(var_val) ? var_val : op_var::direct_var_robust(X, n_elem, norm_type);
257 }
258 else
259 {
260 return T(0);
261 }
262 }
263
264
265
266 //! find the variance of an array (version for complex numbers) (robust but slow)
267 template<typename T>
268 inline
269 T
270 op_var::direct_var_robust(const std::complex<T>* const X, const uword n_elem, const uword norm_type)
271 {
272 arma_extra_debug_sigprint();
273
274 typedef typename std::complex<T> eT;
275
276 if(n_elem > 1)
277 {
278 eT r_mean = X[0];
279 T r_var = T(0);
280
281 for(uword i=1; i<n_elem; ++i)
282 {
283 const eT tmp = X[i] - r_mean;
284 const T i_plus_1 = T(i+1);
285
286 r_var = T(i-1)/T(i) * r_var + std::norm(tmp)/i_plus_1;
287
288 r_mean = r_mean + tmp/i_plus_1;
289 }
290
291 return (norm_type == 0) ? r_var : (T(n_elem-1)/T(n_elem)) * r_var;
292 }
293 else
294 {
295 return T(0);
296 }
297 }
298
299
300
301 //! @}
302