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

Last change on this file since 849 was 849, checked in by MatthewWhiting, 13 years ago
  • Adding the new files to the makefile
  • New functions to find stats for differences between two arrays
  • Implementing some of the new functions in the reconstruction - also making use of the robust stats flag in the Param set.
File size: 16.4 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 findMeanDiff(T *first, T *second, 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 size The length of the array.
59  /// \return The mean value of the array, returned as a float
60  double mean = 0;
61  for(size_t i=0;i<size;i++) mean += double(first[i]-second[i]);
62  if(size>0)
63    mean /= double(size);
64  return float(mean);
65}
66template float findMeanDiff<int>(int *first, int *second, size_t size);
67template float findMeanDiff<long>(long *first, long *second, size_t size);
68template float findMeanDiff<float>(float *first, float *second, size_t size);
69template float findMeanDiff<double>(double *first, double *second, size_t size);
70//--------------------------------------------------------------------
71
72template <class T> float findMean(T *array, bool *mask, size_t size)
73{
74  /// @details
75  /// Find the mean of an array of numbers. Type independent.
76  /// \param array The array of numbers.
77  /// \param mask An array of the same length that says whether to
78  /// include each member of the array in the calculations. Only use
79  /// values where mask=true.
80  /// \param size The length of the array.
81  /// \return The mean value of the array, returned as a float
82  double mean = 0.;
83  int ct=0;
84  for(size_t i=0;i<size;i++){
85    if(mask[i]){
86      mean += double(array[i]);
87      ct++;
88    }
89  }
90  if(ct>0) mean /= double(ct);
91  return float(mean);
92}
93template float findMean<int>(int *array, bool *mask, size_t size);
94template float findMean<long>(long *array, bool *mask, size_t size);
95template float findMean<float>(float *array, bool *mask, size_t size);
96template float findMean<double>(double *array, bool *mask, size_t size);
97//--------------------------------------------------------------------
98
99template <class T> float findMeanDiff(T *first, T *second, bool *mask, size_t size)
100{
101  /// @details
102  /// Find the mean of an array of numbers. Type independent.
103  /// \param array The array of numbers.
104  /// \param mask An array of the same length that says whether to
105  /// include each member of the array in the calculations. Only use
106  /// values where mask=true.
107  /// \param size The length of the array.
108  /// \return The mean value of the array, returned as a float
109  double mean = 0.;
110  int ct=0;
111  for(size_t i=0;i<size;i++){
112    if(mask[i]){
113      mean += double(first[i]-second[i]);
114      ct++;
115    }
116  }
117  if(ct>0) mean /= double(ct);
118  return float(mean);
119}
120template float findMeanDiff<int>(int *first, int *second, bool *mask, size_t size);
121template float findMeanDiff<long>(long *first, long *second, bool *mask, size_t size);
122template float findMeanDiff<float>(float *first, float *second, bool *mask, size_t size);
123template float findMeanDiff<double>(double *first, double *second, bool *mask, size_t size);
124//--------------------------------------------------------------------
125
126template <class T> float findStddev(T *array, size_t size)
127{
128  /// @details Find the rms or standard deviation of an array of
129  /// numbers. Type independent. Calculated by iterating only once,
130  /// using \sum x and \sum x^2 (no call to findMean)
131  /// \param array The array of numbers.
132  /// \param size The length of the array.
133  /// \return The rms value of the array, returned as a float
134
135  // double mean = double(findMean(array,size));
136  // double stddev = (double(array[0])-mean) * (double(array[0])-mean);
137  // for(size_t i=1;i<size;i++) stddev += (double(array[i])-mean)*(double(array[i])-mean);
138  // double stddev = stddev/double(size-1));
139
140  T sumx=0,sumxx=0;
141  double stddev=0;
142  for(size_t i=0;i<size;i++){
143    sumx += array[i];
144    sumxx += (array[i]*array[i]);
145  }
146  if(size>0)
147    stddev = sqrt(double(sumxx)/double(size) - double(sumx*sumx)/double(size*size));
148  return float(stddev);
149}
150template float findStddev<int>(int *array, size_t size);
151template float findStddev<long>(long *array, size_t size);
152template float findStddev<float>(float *array, size_t size);
153template float findStddev<double>(double *array, size_t size);
154//--------------------------------------------------------------------
155
156template <class T> float findStddevDiff(T *first, T *second, size_t size)
157{
158  /// @details Find the rms or standard deviation of an array of
159  /// numbers. Type independent. Calculated by iterating only once,
160  /// using \sum x and \sum x^2 (no call to findMean)
161  /// \param array The array of numbers.
162  /// \param size The length of the array.
163  /// \return The rms value of the array, returned as a float
164
165  T sumx=0,sumxx=0;
166  double stddev=0;
167  for(size_t i=0;i<size;i++){
168    sumx += (first[i]-second[i]);
169    sumxx += ((first[i]-second[i])*(first[i]-second[i]));
170  }
171  if(size>0)
172    stddev = sqrt(double(sumxx)/double(size) - double(sumx*sumx)/double(size*size));
173  return float(stddev);
174}
175template float findStddevDiff<int>(int *first, int *second, size_t size);
176template float findStddevDiff<long>(long *first, long *second, size_t size);
177template float findStddevDiff<float>(float *first, float *second, size_t size);
178template float findStddevDiff<double>(double *first, double *second, size_t size);
179//--------------------------------------------------------------------
180
181template <class T> float findStddev(T *array, bool *mask, size_t size)
182{
183  /// @details Find the rms or standard deviation of an array of
184  /// numbers. Type independent. Calculated by iterating only once,
185  /// using \sum x and \sum x^2 (no call to findMean)
186  /// \param array The array of numbers.
187  /// \param mask An array of the same length that says whether to
188  /// include each member of the array in the calculations. Only use
189  /// values where mask=true.
190  /// \param size The length of the array.
191  /// \return The rms value of the array, returned as a float
192
193  T sumx=0,sumxx=0;
194  double stddev=0;
195  int ct=0;
196  for(size_t i=0;i<size;i++){
197    if(mask[i]){
198      sumx += array[i];
199      sumxx += (array[i]*array[i]);
200      ct++;
201    }
202  }
203  if(ct>0)
204    stddev = sqrt(double(sumxx)/double(ct) - double(sumx*sumx)/double(ct*ct));
205  return float(stddev);
206}
207template float findStddev<int>(int *array, bool *mask, size_t size);
208template float findStddev<long>(long *array, bool *mask, size_t size);
209template float findStddev<float>(float *array, bool *mask, size_t size);
210template float findStddev<double>(double *array, bool *mask, size_t size);
211//--------------------------------------------------------------------
212
213template <class T> float findStddevDiff(T *first, T *second, bool *mask, size_t size)
214{
215  /// @details Find the rms or standard deviation of an array of
216  /// numbers. Type independent. Calculated by iterating only once,
217  /// using \sum x and \sum x^2 (no call to findMean)
218  /// \param array The array of numbers.
219  /// \param mask An array of the same length that says whether to
220  /// include each member of the array in the calculations. Only use
221  /// values where mask=true.
222  /// \param size The length of the array.
223  /// \return The rms value of the array, returned as a float
224
225  T sumx=0,sumxx=0;
226  double stddev=0;
227  int ct=0;
228  for(size_t i=0;i<size;i++){
229    if(mask[i]){
230      sumx += (first[i]-second[i]);
231      sumxx += ((first[i]-second[i])*(first[i]-second[i]));
232      ct++;
233    }
234  }
235  if(ct>0)
236    stddev = sqrt(double(sumxx)/double(ct) - double(sumx*sumx)/double(ct*ct));
237  return float(stddev);
238}
239template float findStddevDiff<int>(int *first, int *second, bool *mask, size_t size);
240template float findStddevDiff<long>(long *first, long *second, bool *mask, size_t size);
241template float findStddevDiff<float>(float *first, float *second, bool *mask, size_t size);
242template float findStddevDiff<double>(double *first, double *second, bool *mask, size_t size);
243//--------------------------------------------------------------------
244
245template <class T> void findNormalStats(T *array, size_t size,
246                                        float &mean, float &stddev)
247{
248  /// @details
249  /// Find the mean and rms or standard deviation of an array of
250  /// numbers. Type independent.
251  ///
252  /// \param array The array of numbers.
253  /// \param size The length of the array.
254  /// \param mean The mean value of the array, returned as a float.
255  /// \param stddev The rms or standard deviation of the array,
256  /// returned as a float.
257
258  if(size==0){
259    std::cerr << "Error in findNormalStats: zero sized array!\n";
260    return;
261  }
262  mean = array[0];
263  for(size_t i=1;i<size;i++){
264    mean += array[i];
265  }
266  mean /= float(size);
267
268  stddev = (array[0]-mean) * (array[0]-mean);
269  for(size_t i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
270  stddev = sqrt(stddev/float(size-1));
271
272}
273template void findNormalStats<int>(int *array, size_t size,
274                                      float &mean, float &stddev);
275template void findNormalStats<long>(long *array, size_t size,
276                                       float &mean, float &stddev);
277template void findNormalStats<float>(float *array, size_t size,
278                                        float &mean, float &stddev);
279template void findNormalStats<double>(double *array, size_t size,
280                                         float &mean, float &stddev);
281//--------------------------------------------------------------------
282
283template <class T> void findNormalStats(T *array, size_t size, bool *mask,
284                                        float &mean, float &stddev)
285{
286  /// @details
287  /// Find the mean and rms or standard deviation of a subset of an
288  /// array of numbers. The subset is defined by an array of bool
289  /// variables. Type independent.
290  ///
291  /// \param array The array of numbers.
292  /// \param size The length of the array.
293  /// \param mask An array of the same length that says whether to
294  /// include each member of the array in the calculations. Only look
295  /// at values where mask=true.
296  /// \param mean The mean value of the array, returned as a float.
297  /// \param stddev The rms or standard deviation of the array,
298  /// returned as a float.
299
300  int goodSize=0;
301  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
302  if(goodSize==0){
303    std::cerr << "Error in findNormalStats: no good values!\n";
304    return;
305  }
306  int start=0;
307  while(!mask[start]){start++;}
308  mean = array[start];
309  for(size_t i=start+1;i<size;i++){
310    if(mask[i]) mean += array[i];
311  }
312  mean /= float(goodSize);
313
314  stddev = (array[start]-mean) * (array[start]-mean);
315  for(size_t i=1;i<size;i++){
316    if(mask[i]) stddev += (array[i]-mean)*(array[i]-mean);
317  }
318  stddev = sqrt(stddev/float(goodSize-1));
319
320}
321template void findNormalStats<int>(int *array, size_t size, bool *mask,
322                                      float &mean, float &stddev);
323template void findNormalStats<long>(long *array, size_t size, bool *mask,
324                                       float &mean, float &stddev);
325template void findNormalStats<float>(float *array, size_t size, bool *mask,
326                                        float &mean, float &stddev);
327template void findNormalStats<double>(double *array, size_t size, bool *mask,
328                                         float &mean, float &stddev);
329//-------------------------------------------------------------------- 
330
331template <class T> void findNormalStatsDiff(T *first, T *second, size_t size,
332                                            float &mean, float &stddev)
333{
334  /// @details
335  /// Find the mean and rms or standard deviation of  the difference between two arrays of
336  /// numbers. The difference is defined as first - second. Type independent.
337  ///
338  /// \param first The first array
339  /// \param second The second array
340  /// \param size The length of the array.
341  /// \param mean The mean value of the array, returned as a float.
342  /// \param stddev The rms or standard deviation of the array,
343  /// returned as a float.
344
345  if(size==0){
346    std::cerr << "Error in findNormalStats: zero sized array!\n";
347    return;
348  }
349  mean = first[0]-second[0];
350  for(size_t i=1;i<size;i++){
351    mean += (first[i]-second[i]);
352  }
353  mean /= float(size);
354
355  stddev = (first[0]-second[0]-mean) * (first[0]-second[0]-mean);
356  for(size_t i=1;i<size;i++) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
357  stddev = sqrt(stddev/float(size-1));
358
359}
360template void findNormalStatsDiff<int>(int *first, int *second, size_t size,
361                                       float &mean, float &stddev);
362template void findNormalStatsDiff<long>(long *first, long *second, size_t size,
363                                        float &mean, float &stddev);
364template void findNormalStatsDiff<float>(float *first, float *second, size_t size,
365                                         float &mean, float &stddev);
366template void findNormalStatsDiff<double>(double *first, double *second, size_t size,
367                                          float &mean, float &stddev);
368//--------------------------------------------------------------------
369
370template <class T> void findNormalStatsDiff(T *first, T *second, size_t size, bool *mask,
371                                            float &mean, float &stddev)
372{
373  /// @details Find the mean and rms or standard deviation of the
374  /// difference between two arrays of numbers, where some elements
375  /// are masked out. The mask is defined by an array of bool
376  /// variables, and the difference is defined as first - second. Type
377  /// independent.
378  ///
379  /// \param first The first array
380  /// \param second The second array
381  /// \param size The length of the array.
382  /// \param mask An array of the same length that says whether to
383  /// include each member of the array in the calculations. Only look
384  /// at values where mask=true.
385  /// \param mean The mean value of the array, returned as a float.
386  /// \param stddev The rms or standard deviation of the array,
387  /// returned as a float.
388
389  int goodSize=0;
390  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
391  if(goodSize==0){
392    std::cerr << "Error in findNormalStats: no good values!\n";
393    return;
394  }
395  int start=0;
396  while(!mask[start]){start++;}
397  mean = first[start]-second[start];
398  for(size_t i=start+1;i<size;i++){
399    if(mask[i]) mean += (first[i]-second[i]);
400  }
401  mean /= float(goodSize);
402
403  stddev = (first[start]-second[start]-mean) * (first[start]-second[start]-mean);
404  for(size_t i=1;i<size;i++){
405    if(mask[i]) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
406  }
407  stddev = sqrt(stddev/float(goodSize-1));
408
409}
410template void findNormalStatsDiff<int>(int *first, int *second, size_t size, bool *mask,
411                                       float &mean, float &stddev);
412template void findNormalStatsDiff<long>(long *first, long *second, size_t size, bool *mask,
413                                        float &mean, float &stddev);
414template void findNormalStatsDiff<float>(float *first, float *second, size_t size, bool *mask,
415                                         float &mean, float &stddev);
416template void findNormalStatsDiff<double>(double *first, double *second, size_t size, bool *mask,
417                                          float &mean, float &stddev);
418//--------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.