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

Last change on this file since 1213 was 892, checked in by MatthewWhiting, 12 years ago

Removing unused, commented-out code

File size: 16.4 KB
RevLine 
[301]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// -----------------------------------------------------------------------
[3]29#include <iostream>
[204]30#include <algorithm>
[3]31#include <math.h>
[393]32#include <duchamp/Utils/utils.hh>
[3]33
[848]34template <class T> float findMean(T *array, size_t size)
[70]35{
[528]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
[848]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);
[653]45  return float(mean);
[53]46}
[848]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);
[190]51//--------------------------------------------------------------------
[53]52
[849]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
[848]72template <class T> float findMean(T *array, bool *mask, size_t size)
[53]73{
[528]74  /// @details
[848]75  /// Find the mean of an array of numbers. Type independent.
[528]76  /// \param array The array of numbers.
[848]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.
[528]80  /// \param size The length of the array.
[848]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    }
[646]89  }
[848]90  if(ct>0) mean /= double(ct);
91  return float(mean);
[53]92}
[848]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);
[190]97//--------------------------------------------------------------------
[53]98
[849]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
[848]126template <class T> float findStddev(T *array, size_t size)
[53]127{
[848]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)
[528]131  /// \param array The array of numbers.
132  /// \param size The length of the array.
[848]133  /// \return The rms value of the array, returned as a float
[646]134
[891]135  double sumx=0.,sumxx=0.;
136  double stddev=0.;
137  double dsize=double(size);
[848]138  for(size_t i=0;i<size;i++){
139    sumx += array[i];
140    sumxx += (array[i]*array[i]);
[756]141  }
[891]142   // std::cerr << sumx << " " << sumxx << " " << size << " " << size*size <<"\n";
143   // std::cerr << double(sumx) << " " << double(sumxx) << " " << double(size) << " " << double(size*size)<< "\n";
144  double mean=sumx/dsize;
[848]145  if(size>0)
[891]146    stddev = sqrt(sumxx/dsize - mean*mean);
147   // std::cerr << stddev << " " << float(stddev) << "\n";
[848]148  return float(stddev);
[756]149}
[848]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);
[756]154//--------------------------------------------------------------------
155
[849]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
[891]165  double sumx=0.,sumxx=0.;
166  double stddev=0.;
167  double dsize=double(size);
[849]168  for(size_t i=0;i<size;i++){
169    sumx += (first[i]-second[i]);
170    sumxx += ((first[i]-second[i])*(first[i]-second[i]));
171  }
[891]172  double mean=sumx/dsize;
[849]173  if(size>0)
[891]174    stddev = sqrt(sumxx/dsize - mean*mean);
[849]175  return float(stddev);
176}
177template float findStddevDiff<int>(int *first, int *second, size_t size);
178template float findStddevDiff<long>(long *first, long *second, size_t size);
179template float findStddevDiff<float>(float *first, float *second, size_t size);
180template float findStddevDiff<double>(double *first, double *second, size_t size);
181//--------------------------------------------------------------------
182
[848]183template <class T> float findStddev(T *array, bool *mask, size_t size)
[3]184{
[848]185  /// @details Find the rms or standard deviation of an array of
186  /// numbers. Type independent. Calculated by iterating only once,
187  /// using \sum x and \sum x^2 (no call to findMean)
[528]188  /// \param array The array of numbers.
189  /// \param mask An array of the same length that says whether to
190  /// include each member of the array in the calculations. Only use
191  /// values where mask=true.
[848]192  /// \param size The length of the array.
193  /// \return The rms value of the array, returned as a float
[528]194
[891]195  double sumx=0.,sumxx=0.;
196  double stddev=0.;
[848]197  int ct=0;
198  for(size_t i=0;i<size;i++){
199    if(mask[i]){
200      sumx += array[i];
201      sumxx += (array[i]*array[i]);
202      ct++;
203    }
[190]204  }
[891]205  double dct=double(ct);
206  double mean=sumx/dct;
[848]207  if(ct>0)
[891]208    stddev = sqrt(sumxx/dct - mean*mean);
[848]209  return float(stddev);
[3]210}
[848]211template float findStddev<int>(int *array, bool *mask, size_t size);
212template float findStddev<long>(long *array, bool *mask, size_t size);
213template float findStddev<float>(float *array, bool *mask, size_t size);
214template float findStddev<double>(double *array, bool *mask, size_t size);
[190]215//--------------------------------------------------------------------
[3]216
[849]217template <class T> float findStddevDiff(T *first, T *second, bool *mask, size_t size)
218{
219  /// @details Find the rms or standard deviation of an array of
220  /// numbers. Type independent. Calculated by iterating only once,
221  /// using \sum x and \sum x^2 (no call to findMean)
222  /// \param array The array of numbers.
223  /// \param mask An array of the same length that says whether to
224  /// include each member of the array in the calculations. Only use
225  /// values where mask=true.
226  /// \param size The length of the array.
227  /// \return The rms value of the array, returned as a float
228
[891]229  double sumx=0,sumxx=0;
[849]230  double stddev=0;
231  int ct=0;
232  for(size_t i=0;i<size;i++){
233    if(mask[i]){
234      sumx += (first[i]-second[i]);
235      sumxx += ((first[i]-second[i])*(first[i]-second[i]));
236      ct++;
237    }
238  }
[891]239  double dct=double(ct);
240  double mean=sumx/dct;
[849]241  if(ct>0)
[891]242    stddev = sqrt(sumxx/dct - mean*mean);
[849]243  return float(stddev);
244}
245template float findStddevDiff<int>(int *first, int *second, bool *mask, size_t size);
246template float findStddevDiff<long>(long *first, long *second, bool *mask, size_t size);
247template float findStddevDiff<float>(float *first, float *second, bool *mask, size_t size);
248template float findStddevDiff<double>(double *first, double *second, bool *mask, size_t size);
249//--------------------------------------------------------------------
250
[848]251template <class T> void findNormalStats(T *array, size_t size,
[190]252                                        float &mean, float &stddev)
[3]253{
[528]254  /// @details
255  /// Find the mean and rms or standard deviation of an array of
256  /// numbers. Type independent.
257  ///
258  /// \param array The array of numbers.
259  /// \param size The length of the array.
260  /// \param mean The mean value of the array, returned as a float.
261  /// \param stddev The rms or standard deviation of the array,
262  /// returned as a float.
263
[190]264  if(size==0){
265    std::cerr << "Error in findNormalStats: zero sized array!\n";
266    return;
267  }
[3]268  mean = array[0];
[848]269  for(size_t i=1;i<size;i++){
[3]270    mean += array[i];
271  }
272  mean /= float(size);
273
[79]274  stddev = (array[0]-mean) * (array[0]-mean);
[848]275  for(size_t i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
[79]276  stddev = sqrt(stddev/float(size-1));
[3]277
278}
[848]279template void findNormalStats<int>(int *array, size_t size,
[222]280                                      float &mean, float &stddev);
[848]281template void findNormalStats<long>(long *array, size_t size,
[222]282                                       float &mean, float &stddev);
[848]283template void findNormalStats<float>(float *array, size_t size,
[222]284                                        float &mean, float &stddev);
[848]285template void findNormalStats<double>(double *array, size_t size,
[222]286                                         float &mean, float &stddev);
[190]287//--------------------------------------------------------------------
[3]288
[848]289template <class T> void findNormalStats(T *array, size_t size, bool *mask,
[190]290                                        float &mean, float &stddev)
[70]291{
[528]292  /// @details
293  /// Find the mean and rms or standard deviation of a subset of an
294  /// array of numbers. The subset is defined by an array of bool
295  /// variables. Type independent.
296  ///
297  /// \param array The array of numbers.
298  /// \param size The length of the array.
299  /// \param mask An array of the same length that says whether to
300  /// include each member of the array in the calculations. Only look
301  /// at values where mask=true.
302  /// \param mean The mean value of the array, returned as a float.
303  /// \param stddev The rms or standard deviation of the array,
304  /// returned as a float.
305
[190]306  int goodSize=0;
[848]307  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
[190]308  if(goodSize==0){
309    std::cerr << "Error in findNormalStats: no good values!\n";
310    return;
311  }
312  int start=0;
[275]313  while(!mask[start]){start++;}
[190]314  mean = array[start];
[848]315  for(size_t i=start+1;i<size;i++){
[275]316    if(mask[i]) mean += array[i];
[190]317  }
318  mean /= float(goodSize);
[70]319
[190]320  stddev = (array[start]-mean) * (array[start]-mean);
[848]321  for(size_t i=1;i<size;i++){
[275]322    if(mask[i]) stddev += (array[i]-mean)*(array[i]-mean);
[190]323  }
324  stddev = sqrt(stddev/float(goodSize-1));
325
326}
[848]327template void findNormalStats<int>(int *array, size_t size, bool *mask,
[222]328                                      float &mean, float &stddev);
[848]329template void findNormalStats<long>(long *array, size_t size, bool *mask,
[222]330                                       float &mean, float &stddev);
[848]331template void findNormalStats<float>(float *array, size_t size, bool *mask,
[222]332                                        float &mean, float &stddev);
[848]333template void findNormalStats<double>(double *array, size_t size, bool *mask,
[222]334                                         float &mean, float &stddev);
[848]335//-------------------------------------------------------------------- 
[275]336
[848]337template <class T> void findNormalStatsDiff(T *first, T *second, size_t size,
338                                            float &mean, float &stddev)
[275]339{
[528]340  /// @details
[848]341  /// Find the mean and rms or standard deviation of  the difference between two arrays of
342  /// numbers. The difference is defined as first - second. Type independent.
[528]343  ///
[848]344  /// \param first The first array
345  /// \param second The second array
[528]346  /// \param size The length of the array.
347  /// \param mean The mean value of the array, returned as a float.
348  /// \param stddev The rms or standard deviation of the array,
349  /// returned as a float.
350
[275]351  if(size==0){
[848]352    std::cerr << "Error in findNormalStats: zero sized array!\n";
[275]353    return;
354  }
[848]355  mean = first[0]-second[0];
356  for(size_t i=1;i<size;i++){
357    mean += (first[i]-second[i]);
358  }
359  mean /= float(size);
[275]360
[848]361  stddev = (first[0]-second[0]-mean) * (first[0]-second[0]-mean);
362  for(size_t i=1;i<size;i++) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
363  stddev = sqrt(stddev/float(size-1));
[275]364
365}
[848]366template void findNormalStatsDiff<int>(int *first, int *second, size_t size,
367                                       float &mean, float &stddev);
368template void findNormalStatsDiff<long>(long *first, long *second, size_t size,
369                                        float &mean, float &stddev);
370template void findNormalStatsDiff<float>(float *first, float *second, size_t size,
371                                         float &mean, float &stddev);
372template void findNormalStatsDiff<double>(double *first, double *second, size_t size,
373                                          float &mean, float &stddev);
[275]374//--------------------------------------------------------------------
375
[848]376template <class T> void findNormalStatsDiff(T *first, T *second, size_t size, bool *mask,
377                                            float &mean, float &stddev)
[275]378{
[848]379  /// @details Find the mean and rms or standard deviation of the
380  /// difference between two arrays of numbers, where some elements
381  /// are masked out. The mask is defined by an array of bool
382  /// variables, and the difference is defined as first - second. Type
383  /// independent.
[528]384  ///
[848]385  /// \param first The first array
386  /// \param second The second array
[528]387  /// \param size The length of the array.
388  /// \param mask An array of the same length that says whether to
389  /// include each member of the array in the calculations. Only look
390  /// at values where mask=true.
391  /// \param mean The mean value of the array, returned as a float.
392  /// \param stddev The rms or standard deviation of the array,
393  /// returned as a float.
394
[275]395  int goodSize=0;
[848]396  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
[275]397  if(goodSize==0){
[848]398    std::cerr << "Error in findNormalStats: no good values!\n";
[275]399    return;
400  }
[848]401  int start=0;
402  while(!mask[start]){start++;}
403  mean = first[start]-second[start];
404  for(size_t i=start+1;i<size;i++){
405    if(mask[i]) mean += (first[i]-second[i]);
406  }
407  mean /= float(goodSize);
[275]408
[848]409  stddev = (first[start]-second[start]-mean) * (first[start]-second[start]-mean);
410  for(size_t i=1;i<size;i++){
411    if(mask[i]) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
412  }
413  stddev = sqrt(stddev/float(goodSize-1));
[275]414
415}
[848]416template void findNormalStatsDiff<int>(int *first, int *second, size_t size, bool *mask,
417                                       float &mean, float &stddev);
418template void findNormalStatsDiff<long>(long *first, long *second, size_t size, bool *mask,
419                                        float &mean, float &stddev);
420template void findNormalStatsDiff<float>(float *first, float *second, size_t size, bool *mask,
421                                         float &mean, float &stddev);
422template void findNormalStatsDiff<double>(double *first, double *second, size_t size, bool *mask,
423                                          float &mean, float &stddev);
[275]424//--------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.