source: trunk/src/Utils/getNormalStats.cc @ 848

Last change on this file since 848 was 848, checked in by MatthewWhiting, 13 years ago

Splitting the getStats functions to have the robust and normal functions in separate files. Keep generic stuff in getStats.cc

File size: 12.1 KB
Line 
1// -----------------------------------------------------------------------
2// getStats.cc: Basic functions to calculate statistical parameters
3//              such as mean, median, rms, madfm, min, max.
4// -----------------------------------------------------------------------
5// Copyright (C) 2006, Matthew Whiting, ATNF
6//
7// This program is free software; you can redistribute it and/or modify it
8// under the terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2 of the License, or (at your
10// option) any later version.
11//
12// Duchamp is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15// for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with Duchamp; if not, write to the Free Software Foundation,
19// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
20//
21// Correspondence concerning Duchamp may be directed to:
22//    Internet email: Matthew.Whiting [at] atnf.csiro.au
23//    Postal address: Dr. Matthew Whiting
24//                    Australia Telescope National Facility, CSIRO
25//                    PO Box 76
26//                    Epping NSW 1710
27//                    AUSTRALIA
28// -----------------------------------------------------------------------
29#include <iostream>
30#include <algorithm>
31#include <math.h>
32#include <duchamp/Utils/utils.hh>
33
34template <class T> float findMean(T *array, size_t size)
35{
36  /// @details
37  /// Find the mean of an array of numbers. Type independent.
38  /// \param array The array of numbers.
39  /// \param size The length of the array.
40  /// \return The mean value of the array, returned as a float
41  double mean = 0;
42  for(size_t i=0;i<size;i++) mean += double(array[i]);
43  if(size>0)
44    mean /= double(size);
45  return float(mean);
46}
47template float findMean<int>(int *array, size_t size);
48template float findMean<long>(long *array, size_t size);
49template float findMean<float>(float *array, size_t size);
50template float findMean<double>(double *array, size_t size);
51//--------------------------------------------------------------------
52
53template <class T> float findMean(T *array, bool *mask, size_t size)
54{
55  /// @details
56  /// Find the mean of an array of numbers. Type independent.
57  /// \param array The array of numbers.
58  /// \param mask An array of the same length that says whether to
59  /// include each member of the array in the calculations. Only use
60  /// values where mask=true.
61  /// \param size The length of the array.
62  /// \return The mean value of the array, returned as a float
63  double mean = 0.;
64  int ct=0;
65  for(size_t i=0;i<size;i++){
66    if(mask[i]){
67      mean += double(array[i]);
68      ct++;
69    }
70  }
71  if(ct>0) mean /= double(ct);
72  return float(mean);
73}
74template float findMean<int>(int *array, bool *mask, size_t size);
75template float findMean<long>(long *array, bool *mask, size_t size);
76template float findMean<float>(float *array, bool *mask, size_t size);
77template float findMean<double>(double *array, bool *mask, size_t size);
78//--------------------------------------------------------------------
79
80template <class T> float findStddev(T *array, size_t size)
81{
82  /// @details Find the rms or standard deviation of an array of
83  /// numbers. Type independent. Calculated by iterating only once,
84  /// using \sum x and \sum x^2 (no call to findMean)
85  /// \param array The array of numbers.
86  /// \param size The length of the array.
87  /// \return The rms value of the array, returned as a float
88
89  // double mean = double(findMean(array,size));
90  // double stddev = (double(array[0])-mean) * (double(array[0])-mean);
91  // for(size_t i=1;i<size;i++) stddev += (double(array[i])-mean)*(double(array[i])-mean);
92  // double stddev = stddev/double(size-1));
93
94  T sumx=0,sumxx=0;
95  double stddev=0;
96  for(size_t i=0;i<size;i++){
97    sumx += array[i];
98    sumxx += (array[i]*array[i]);
99  }
100  if(size>0)
101    stddev = sqrt(double(sumxx)/double(size) - double(sumx*sumx)/double(size*size));
102  return float(stddev);
103}
104template float findStddev<int>(int *array, size_t size);
105template float findStddev<long>(long *array, size_t size);
106template float findStddev<float>(float *array, size_t size);
107template float findStddev<double>(double *array, size_t size);
108//--------------------------------------------------------------------
109
110template <class T> float findStddev(T *array, bool *mask, size_t size)
111{
112  /// @details Find the rms or standard deviation of an array of
113  /// numbers. Type independent. Calculated by iterating only once,
114  /// using \sum x and \sum x^2 (no call to findMean)
115  /// \param array The array of numbers.
116  /// \param mask An array of the same length that says whether to
117  /// include each member of the array in the calculations. Only use
118  /// values where mask=true.
119  /// \param size The length of the array.
120  /// \return The rms value of the array, returned as a float
121
122  T sumx=0,sumxx=0;
123  double stddev=0;
124  int ct=0;
125  for(size_t i=0;i<size;i++){
126    if(mask[i]){
127      sumx += array[i];
128      sumxx += (array[i]*array[i]);
129      ct++;
130    }
131  }
132  if(ct>0)
133    stddev = sqrt(double(sumxx)/double(ct) - double(sumx*sumx)/double(ct*ct));
134  return float(stddev);
135}
136template float findStddev<int>(int *array, bool *mask, size_t size);
137template float findStddev<long>(long *array, bool *mask, size_t size);
138template float findStddev<float>(float *array, bool *mask, size_t size);
139template float findStddev<double>(double *array, bool *mask, size_t size);
140//--------------------------------------------------------------------
141
142template <class T> void findNormalStats(T *array, size_t size,
143                                        float &mean, float &stddev)
144{
145  /// @details
146  /// Find the mean and rms or standard deviation of an array of
147  /// numbers. Type independent.
148  ///
149  /// \param array The array of numbers.
150  /// \param size The length of the array.
151  /// \param mean The mean value of the array, returned as a float.
152  /// \param stddev The rms or standard deviation of the array,
153  /// returned as a float.
154
155  if(size==0){
156    std::cerr << "Error in findNormalStats: zero sized array!\n";
157    return;
158  }
159  mean = array[0];
160  for(size_t i=1;i<size;i++){
161    mean += array[i];
162  }
163  mean /= float(size);
164
165  stddev = (array[0]-mean) * (array[0]-mean);
166  for(size_t i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
167  stddev = sqrt(stddev/float(size-1));
168
169}
170template void findNormalStats<int>(int *array, size_t size,
171                                      float &mean, float &stddev);
172template void findNormalStats<long>(long *array, size_t size,
173                                       float &mean, float &stddev);
174template void findNormalStats<float>(float *array, size_t size,
175                                        float &mean, float &stddev);
176template void findNormalStats<double>(double *array, size_t size,
177                                         float &mean, float &stddev);
178//--------------------------------------------------------------------
179
180template <class T> void findNormalStats(T *array, size_t size, bool *mask,
181                                        float &mean, float &stddev)
182{
183  /// @details
184  /// Find the mean and rms or standard deviation of a subset of an
185  /// array of numbers. The subset is defined by an array of bool
186  /// variables. Type independent.
187  ///
188  /// \param array The array of numbers.
189  /// \param size The length of the array.
190  /// \param mask An array of the same length that says whether to
191  /// include each member of the array in the calculations. Only look
192  /// at values where mask=true.
193  /// \param mean The mean value of the array, returned as a float.
194  /// \param stddev The rms or standard deviation of the array,
195  /// returned as a float.
196
197  int goodSize=0;
198  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
199  if(goodSize==0){
200    std::cerr << "Error in findNormalStats: no good values!\n";
201    return;
202  }
203  int start=0;
204  while(!mask[start]){start++;}
205  mean = array[start];
206  for(size_t i=start+1;i<size;i++){
207    if(mask[i]) mean += array[i];
208  }
209  mean /= float(goodSize);
210
211  stddev = (array[start]-mean) * (array[start]-mean);
212  for(size_t i=1;i<size;i++){
213    if(mask[i]) stddev += (array[i]-mean)*(array[i]-mean);
214  }
215  stddev = sqrt(stddev/float(goodSize-1));
216
217}
218template void findNormalStats<int>(int *array, size_t size, bool *mask,
219                                      float &mean, float &stddev);
220template void findNormalStats<long>(long *array, size_t size, bool *mask,
221                                       float &mean, float &stddev);
222template void findNormalStats<float>(float *array, size_t size, bool *mask,
223                                        float &mean, float &stddev);
224template void findNormalStats<double>(double *array, size_t size, bool *mask,
225                                         float &mean, float &stddev);
226//-------------------------------------------------------------------- 
227
228template <class T> void findNormalStatsDiff(T *first, T *second, size_t size,
229                                            float &mean, float &stddev)
230{
231  /// @details
232  /// Find the mean and rms or standard deviation of  the difference between two arrays of
233  /// numbers. The difference is defined as first - second. Type independent.
234  ///
235  /// \param first The first array
236  /// \param second The second array
237  /// \param size The length of the array.
238  /// \param mean The mean value of the array, returned as a float.
239  /// \param stddev The rms or standard deviation of the array,
240  /// returned as a float.
241
242  if(size==0){
243    std::cerr << "Error in findNormalStats: zero sized array!\n";
244    return;
245  }
246  mean = first[0]-second[0];
247  for(size_t i=1;i<size;i++){
248    mean += (first[i]-second[i]);
249  }
250  mean /= float(size);
251
252  stddev = (first[0]-second[0]-mean) * (first[0]-second[0]-mean);
253  for(size_t i=1;i<size;i++) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
254  stddev = sqrt(stddev/float(size-1));
255
256}
257template void findNormalStatsDiff<int>(int *first, int *second, size_t size,
258                                       float &mean, float &stddev);
259template void findNormalStatsDiff<long>(long *first, long *second, size_t size,
260                                        float &mean, float &stddev);
261template void findNormalStatsDiff<float>(float *first, float *second, size_t size,
262                                         float &mean, float &stddev);
263template void findNormalStatsDiff<double>(double *first, double *second, size_t size,
264                                          float &mean, float &stddev);
265//--------------------------------------------------------------------
266
267template <class T> void findNormalStatsDiff(T *first, T *second, size_t size, bool *mask,
268                                            float &mean, float &stddev)
269{
270  /// @details Find the mean and rms or standard deviation of the
271  /// difference between two arrays of numbers, where some elements
272  /// are masked out. The mask is defined by an array of bool
273  /// variables, and the difference is defined as first - second. Type
274  /// independent.
275  ///
276  /// \param first The first array
277  /// \param second The second array
278  /// \param size The length of the array.
279  /// \param mask An array of the same length that says whether to
280  /// include each member of the array in the calculations. Only look
281  /// at values where mask=true.
282  /// \param mean The mean value of the array, returned as a float.
283  /// \param stddev The rms or standard deviation of the array,
284  /// returned as a float.
285
286  int goodSize=0;
287  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
288  if(goodSize==0){
289    std::cerr << "Error in findNormalStats: no good values!\n";
290    return;
291  }
292  int start=0;
293  while(!mask[start]){start++;}
294  mean = first[start]-second[start];
295  for(size_t i=start+1;i<size;i++){
296    if(mask[i]) mean += (first[i]-second[i]);
297  }
298  mean /= float(goodSize);
299
300  stddev = (first[start]-second[start]-mean) * (first[start]-second[start]-mean);
301  for(size_t i=1;i<size;i++){
302    if(mask[i]) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
303  }
304  stddev = sqrt(stddev/float(goodSize-1));
305
306}
307template void findNormalStatsDiff<int>(int *first, int *second, size_t size, bool *mask,
308                                       float &mean, float &stddev);
309template void findNormalStatsDiff<long>(long *first, long *second, size_t size, bool *mask,
310                                        float &mean, float &stddev);
311template void findNormalStatsDiff<float>(float *first, float *second, size_t size, bool *mask,
312                                         float &mean, float &stddev);
313template void findNormalStatsDiff<double>(double *first, double *second, size_t size, bool *mask,
314                                          float &mean, float &stddev);
315//--------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.