max@0
|
1 // Copyright (C) 2009-2011 NICTA (www.nicta.com.au)
|
max@0
|
2 // Copyright (C) 2009-2011 Conrad Sanderson
|
max@0
|
3 //
|
max@0
|
4 // This file is part of the Armadillo C++ library.
|
max@0
|
5 // It is provided without any warranty of fitness
|
max@0
|
6 // for any purpose. You can redistribute this file
|
max@0
|
7 // and/or modify it under the terms of the GNU
|
max@0
|
8 // Lesser General Public License (LGPL) as published
|
max@0
|
9 // by the Free Software Foundation, either version 3
|
max@0
|
10 // of the License or (at your option) any later version.
|
max@0
|
11 // (see http://www.opensource.org/licenses for more info)
|
max@0
|
12
|
max@0
|
13
|
max@0
|
14 //! \addtogroup op_mean
|
max@0
|
15 //! @{
|
max@0
|
16
|
max@0
|
17
|
max@0
|
18
|
max@0
|
19 template<typename eT>
|
max@0
|
20 arma_pure
|
max@0
|
21 inline
|
max@0
|
22 eT
|
max@0
|
23 op_mean::direct_mean(const eT* const X, const uword n_elem)
|
max@0
|
24 {
|
max@0
|
25 arma_extra_debug_sigprint();
|
max@0
|
26
|
max@0
|
27 typedef typename get_pod_type<eT>::result T;
|
max@0
|
28
|
max@0
|
29 const eT result = arrayops::accumulate(X, n_elem) / T(n_elem);
|
max@0
|
30
|
max@0
|
31 return arma_isfinite(result) ? result : op_mean::direct_mean_robust(X, n_elem);
|
max@0
|
32 }
|
max@0
|
33
|
max@0
|
34
|
max@0
|
35
|
max@0
|
36 template<typename eT>
|
max@0
|
37 inline
|
max@0
|
38 eT
|
max@0
|
39 op_mean::direct_mean(const Mat<eT>& X, const uword row)
|
max@0
|
40 {
|
max@0
|
41 arma_extra_debug_sigprint();
|
max@0
|
42
|
max@0
|
43 typedef typename get_pod_type<eT>::result T;
|
max@0
|
44
|
max@0
|
45 const uword X_n_cols = X.n_cols;
|
max@0
|
46
|
max@0
|
47 eT val = eT(0);
|
max@0
|
48
|
max@0
|
49 for(uword col=0; col<X_n_cols; ++col)
|
max@0
|
50 {
|
max@0
|
51 val += X.at(row,col);
|
max@0
|
52 }
|
max@0
|
53
|
max@0
|
54 const eT result = val / T(X_n_cols);
|
max@0
|
55
|
max@0
|
56 return arma_isfinite(result) ? result : direct_mean_robust(X, row);
|
max@0
|
57 }
|
max@0
|
58
|
max@0
|
59
|
max@0
|
60
|
max@0
|
61 template<typename eT>
|
max@0
|
62 inline
|
max@0
|
63 eT
|
max@0
|
64 op_mean::direct_mean(const subview<eT>& X)
|
max@0
|
65 {
|
max@0
|
66 arma_extra_debug_sigprint();
|
max@0
|
67
|
max@0
|
68 typedef typename get_pod_type<eT>::result T;
|
max@0
|
69
|
max@0
|
70 const uword X_n_elem = X.n_elem;
|
max@0
|
71
|
max@0
|
72 eT val = eT(0);
|
max@0
|
73
|
max@0
|
74 for(uword i=0; i<X_n_elem; ++i)
|
max@0
|
75 {
|
max@0
|
76 val += X[i];
|
max@0
|
77 }
|
max@0
|
78
|
max@0
|
79 const eT result = val / T(X_n_elem);
|
max@0
|
80
|
max@0
|
81 return arma_isfinite(result) ? result : direct_mean_robust(X);
|
max@0
|
82 }
|
max@0
|
83
|
max@0
|
84
|
max@0
|
85
|
max@0
|
86 template<typename eT>
|
max@0
|
87 inline
|
max@0
|
88 eT
|
max@0
|
89 op_mean::direct_mean(const diagview<eT>& X)
|
max@0
|
90 {
|
max@0
|
91 arma_extra_debug_sigprint();
|
max@0
|
92
|
max@0
|
93 typedef typename get_pod_type<eT>::result T;
|
max@0
|
94
|
max@0
|
95 const uword X_n_elem = X.n_elem;
|
max@0
|
96
|
max@0
|
97 eT val = eT(0);
|
max@0
|
98
|
max@0
|
99 for(uword i=0; i<X_n_elem; ++i)
|
max@0
|
100 {
|
max@0
|
101 val += X[i];
|
max@0
|
102 }
|
max@0
|
103
|
max@0
|
104 const eT result = val / T(X_n_elem);
|
max@0
|
105
|
max@0
|
106 return arma_isfinite(result) ? result : direct_mean_robust(X);
|
max@0
|
107 }
|
max@0
|
108
|
max@0
|
109
|
max@0
|
110
|
max@0
|
111 //! \brief
|
max@0
|
112 //! For each row or for each column, find the mean value.
|
max@0
|
113 //! The result is stored in a dense matrix that has either one column or one row.
|
max@0
|
114 //! The dimension, for which the means are found, is set via the mean() function.
|
max@0
|
115 template<typename T1>
|
max@0
|
116 inline
|
max@0
|
117 void
|
max@0
|
118 op_mean::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_mean>& in)
|
max@0
|
119 {
|
max@0
|
120 arma_extra_debug_sigprint();
|
max@0
|
121
|
max@0
|
122 typedef typename T1::elem_type eT;
|
max@0
|
123 typedef typename get_pod_type<eT>::result T;
|
max@0
|
124
|
max@0
|
125 const unwrap_check<T1> tmp(in.m, out);
|
max@0
|
126 const Mat<eT>& X = tmp.M;
|
max@0
|
127
|
max@0
|
128 const uword dim = in.aux_uword_a;
|
max@0
|
129 arma_debug_check( (dim > 1), "mean(): incorrect usage. dim must be 0 or 1");
|
max@0
|
130
|
max@0
|
131 const uword X_n_rows = X.n_rows;
|
max@0
|
132 const uword X_n_cols = X.n_cols;
|
max@0
|
133
|
max@0
|
134 if(dim == 0)
|
max@0
|
135 {
|
max@0
|
136 arma_extra_debug_print("op_mean::apply(), dim = 0");
|
max@0
|
137
|
max@0
|
138 out.set_size( (X_n_rows > 0) ? 1 : 0, X_n_cols );
|
max@0
|
139
|
max@0
|
140 if(X_n_rows > 0)
|
max@0
|
141 {
|
max@0
|
142 eT* out_mem = out.memptr();
|
max@0
|
143
|
max@0
|
144 for(uword col=0; col<X_n_cols; ++col)
|
max@0
|
145 {
|
max@0
|
146 out_mem[col] = op_mean::direct_mean( X.colptr(col), X_n_rows );
|
max@0
|
147 }
|
max@0
|
148 }
|
max@0
|
149 }
|
max@0
|
150 else
|
max@0
|
151 if(dim == 1)
|
max@0
|
152 {
|
max@0
|
153 arma_extra_debug_print("op_mean::apply(), dim = 1");
|
max@0
|
154
|
max@0
|
155 out.set_size(X_n_rows, (X_n_cols > 0) ? 1 : 0);
|
max@0
|
156
|
max@0
|
157 if(X_n_cols > 0)
|
max@0
|
158 {
|
max@0
|
159 eT* out_mem = out.memptr();
|
max@0
|
160
|
max@0
|
161 for(uword row=0; row<X_n_rows; ++row)
|
max@0
|
162 {
|
max@0
|
163 out_mem[row] = op_mean::direct_mean( X, row );
|
max@0
|
164 }
|
max@0
|
165 }
|
max@0
|
166 }
|
max@0
|
167 }
|
max@0
|
168
|
max@0
|
169
|
max@0
|
170
|
max@0
|
171 template<typename eT>
|
max@0
|
172 arma_pure
|
max@0
|
173 inline
|
max@0
|
174 eT
|
max@0
|
175 op_mean::direct_mean_robust(const eT* const X, const uword n_elem)
|
max@0
|
176 {
|
max@0
|
177 arma_extra_debug_sigprint();
|
max@0
|
178
|
max@0
|
179 // use an adapted form of the mean finding algorithm from the running_stat class
|
max@0
|
180
|
max@0
|
181 typedef typename get_pod_type<eT>::result T;
|
max@0
|
182
|
max@0
|
183 uword i,j;
|
max@0
|
184
|
max@0
|
185 eT r_mean = eT(0);
|
max@0
|
186
|
max@0
|
187 for(i=0, j=1; j<n_elem; i+=2, j+=2)
|
max@0
|
188 {
|
max@0
|
189 const eT Xi = X[i];
|
max@0
|
190 const eT Xj = X[j];
|
max@0
|
191
|
max@0
|
192 r_mean = r_mean + (Xi - r_mean)/T(j); // we need i+1, and j is equivalent to i+1 here
|
max@0
|
193 r_mean = r_mean + (Xj - r_mean)/T(j+1);
|
max@0
|
194 }
|
max@0
|
195
|
max@0
|
196
|
max@0
|
197 if(i < n_elem)
|
max@0
|
198 {
|
max@0
|
199 const eT Xi = X[i];
|
max@0
|
200
|
max@0
|
201 r_mean = r_mean + (Xi - r_mean)/T(i+1);
|
max@0
|
202 }
|
max@0
|
203
|
max@0
|
204 return r_mean;
|
max@0
|
205 }
|
max@0
|
206
|
max@0
|
207
|
max@0
|
208
|
max@0
|
209 template<typename eT>
|
max@0
|
210 inline
|
max@0
|
211 eT
|
max@0
|
212 op_mean::direct_mean_robust(const Mat<eT>& X, const uword row)
|
max@0
|
213 {
|
max@0
|
214 arma_extra_debug_sigprint();
|
max@0
|
215
|
max@0
|
216 typedef typename get_pod_type<eT>::result T;
|
max@0
|
217
|
max@0
|
218 const uword X_n_cols = X.n_cols;
|
max@0
|
219
|
max@0
|
220 eT r_mean = eT(0);
|
max@0
|
221
|
max@0
|
222 for(uword col=0; col<X_n_cols; ++col)
|
max@0
|
223 {
|
max@0
|
224 r_mean = r_mean + (X.at(row,col) - r_mean)/T(col+1);
|
max@0
|
225 }
|
max@0
|
226
|
max@0
|
227 return r_mean;
|
max@0
|
228 }
|
max@0
|
229
|
max@0
|
230
|
max@0
|
231
|
max@0
|
232 template<typename eT>
|
max@0
|
233 inline
|
max@0
|
234 eT
|
max@0
|
235 op_mean::direct_mean_robust(const subview<eT>& X)
|
max@0
|
236 {
|
max@0
|
237 arma_extra_debug_sigprint();
|
max@0
|
238
|
max@0
|
239 typedef typename get_pod_type<eT>::result T;
|
max@0
|
240
|
max@0
|
241 const uword X_n_elem = X.n_elem;
|
max@0
|
242
|
max@0
|
243 eT r_mean = eT(0);
|
max@0
|
244
|
max@0
|
245 for(uword i=0; i<X_n_elem; ++i)
|
max@0
|
246 {
|
max@0
|
247 r_mean = r_mean + (X[i] - r_mean)/T(i+1);
|
max@0
|
248 }
|
max@0
|
249
|
max@0
|
250 return r_mean;
|
max@0
|
251 }
|
max@0
|
252
|
max@0
|
253
|
max@0
|
254
|
max@0
|
255 template<typename eT>
|
max@0
|
256 inline
|
max@0
|
257 eT
|
max@0
|
258 op_mean::direct_mean_robust(const diagview<eT>& X)
|
max@0
|
259 {
|
max@0
|
260 arma_extra_debug_sigprint();
|
max@0
|
261
|
max@0
|
262 typedef typename get_pod_type<eT>::result T;
|
max@0
|
263
|
max@0
|
264 const uword X_n_elem = X.n_elem;
|
max@0
|
265
|
max@0
|
266 eT r_mean = eT(0);
|
max@0
|
267
|
max@0
|
268 for(uword i=0; i<X_n_elem; ++i)
|
max@0
|
269 {
|
max@0
|
270 r_mean = r_mean + (X[i] - r_mean)/T(i+1);
|
max@0
|
271 }
|
max@0
|
272
|
max@0
|
273 return r_mean;
|
max@0
|
274 }
|
max@0
|
275
|
max@0
|
276
|
max@0
|
277
|
max@0
|
278 //! @}
|
max@0
|
279
|