source: tags/release-1.1.8/src/Utils/getStats.cc @ 1391

Last change on this file since 1391 was 528, checked in by MatthewWhiting, 15 years ago

Changing the documentation comments to match the askapsoft style. Also have split ChanMap? and Object3D into separate files.

File size: 17.3 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> T absval(T value)
35{
36  /// Type-independent way of getting the absolute value.
37  if( value > 0) return value;
38  else return 0-value;
39}
40template int absval<int>(int value);
41template long absval<long>(long value);
42template float absval<float>(float value);
43template double absval<double>(double value);
44//--------------------------------------------------------------------
45
46template <class T> void findMinMax(const T *array, const int size,
47                                   T &min, T &max)
48{
49  /// @details
50  /// A function to find the minimum and maximum values of a set of numbers.
51  /// \param array The array of data values. Type independent.
52  /// \param size The length of the array
53  /// \param min The returned value of the minimum value in the array.
54  /// \param max The returned value of the maximum value in the array.
55  min = max = array[0];
56  for(int i=1;i<size;i++) {
57    if(array[i]<min) min=array[i];
58    if(array[i]>max) max=array[i];
59  }
60}
61template void findMinMax<int>(const int *array, const int size,
62                                 int &min, int &max);
63template void findMinMax<long>(const long *array, const int size,
64                                  long &min, long &max);
65template void findMinMax<float>(const float *array, const int size,
66                                   float &min, float &max);
67template void findMinMax<double>(const double *array, const int size,
68                                    double &min, double &max);
69//--------------------------------------------------------------------
70
71template <class T> float findMean(T *array, int size)
72{
73  /// @details
74  /// Find the mean of an array of numbers. Type independent.
75  /// \param array The array of numbers.
76  /// \param size The length of the array.
77  /// \return The mean value of the array, returned as a float
78  float mean = array[0];
79  for(int i=1;i<size;i++) mean += array[i];
80  mean /= float(size);
81  return mean;
82}
83template float findMean<int>(int *array, int size);
84template float findMean<long>(long *array, int size);
85template float findMean<float>(float *array, int size);
86template float findMean<double>(double *array, int size);
87//--------------------------------------------------------------------
88
89template <class T> float findStddev(T *array, int size)
90{
91  /// @details
92  /// Find the rms or standard deviation of an array of numbers. Type independent.
93  /// \param array The array of numbers.
94  /// \param size The length of the array.
95  /// \return The rms value of the array, returned as a float
96  float mean = findMean(array,size);
97  float stddev = (array[0]-mean) * (array[0]-mean);
98  for(int i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
99  stddev = sqrt(stddev/float(size-1));
100  return stddev;
101}
102template float findStddev<int>(int *array, int size);
103template float findStddev<long>(long *array, int size);
104template float findStddev<float>(float *array, int size);
105template float findStddev<double>(double *array, int size);
106//--------------------------------------------------------------------
107
108template <class T> T findMedian(T *array, int size)
109{
110  /// @details
111  /// Find the median value of an array of numbers. Type independent.
112  /// \param array The array of numbers.
113  /// \param size The length of the array.
114  /// \return The median value of the array, returned as the same type as the array.
115  T *newarray = new T[size];
116  T median;
117  for(int i=0;i<size;i++) newarray[i] = array[i];
118  std::sort(newarray,newarray+size);
119  if((size%2)==0) median = (newarray[size/2-1]+newarray[size/2])/2;
120  else median = newarray[size/2];
121  delete [] newarray;
122  return median;
123}
124template int findMedian<int>(int *array, int size);
125template long findMedian<long>(long *array, int size);
126template float findMedian<float>(float *array, int size);
127template double findMedian<double>(double *array, int size);
128//--------------------------------------------------------------------
129
130template <class T> T findMADFM(T *array, int size)
131{
132  /// @details
133  /// Find the median absolute deviation from the median value of an
134  /// array of numbers. Type independent.
135  ///
136  /// \param array The array of numbers.
137  /// \param size The length of the array.
138  /// \return The median absolute deviation from the median value of
139  /// the array, returned as the same type as the array.
140  T *newarray = new T[size];
141  T median = findMedian<T>(array,size);
142  T madfm;
143  for(int i=0;i<size;i++) newarray[i] = absval(array[i]-median);
144  std::sort(newarray,newarray+size);
145  if((size%2)==0) madfm = (newarray[size/2-1]+newarray[size/2])/2;
146  else madfm = newarray[size/2];
147  delete [] newarray;
148  return madfm;
149}
150template int findMADFM<int>(int *array, int size);
151template long findMADFM<long>(long *array, int size);
152template float findMADFM<float>(float *array, int size);
153template double findMADFM<double>(double *array, int size);
154//--------------------------------------------------------------------
155
156template <class T> void findMedianStats(T *array, int size,
157                                        T &median, T &madfm)
158{
159  /// @details
160  /// Find the median and the median absolute deviation from the median
161  /// value of an array of numbers. Type independent.
162  ///
163  /// \param array The array of numbers.
164  /// \param size The length of the array.
165  /// \param median The median value of the array, returned as the same
166  /// type as the array.
167  /// \param madfm The median absolute deviation from the median value
168  /// of the array, returned as the same type as the array.
169  if(size==0){
170    std::cerr << "Error in findMedianStats: zero sized array!\n";
171    return;
172  }
173  T *newarray = new T[size];
174
175  for(int i=0;i<size;i++) newarray[i] = array[i];
176  std::sort(newarray,newarray+size);
177  if((size%2)==0) median = (newarray[size/2-1]+newarray[size/2])/2;
178  else median = newarray[size/2];
179
180  for(int i=0;i<size;i++) newarray[i] = absval(array[i]-median);
181  std::sort(newarray,newarray+size);
182  if((size%2)==0) madfm = (newarray[size/2-1]+newarray[size/2])/2;
183  else madfm = newarray[size/2];
184
185  delete [] newarray;
186}
187template void findMedianStats<int>(int *array, int size,
188                                      int &median, int &madfm);
189template void findMedianStats<long>(long *array, int size,
190                                       long &median, long &madfm);
191template void findMedianStats<float>(float *array, int size,
192                                        float &median, float &madfm);
193template void findMedianStats<double>(double *array, int size,
194                                         double &median, double &madfm);
195//--------------------------------------------------------------------
196
197template <class T> void findMedianStats(T *array, int size, bool *mask,
198                                        T &median, T &madfm)
199{
200  /// @details
201  /// Find the median and the median absolute deviation from the median
202  /// value of a subset of an array of numbers. The subset is defined
203  /// by an array of bool variables. Type independent.
204  ///
205  /// \param array The array of numbers.
206  /// \param size The length of the array.
207  /// \param mask An array of the same length that says whether to
208  /// include each member of the array in the calculations. Only use
209  /// values where mask=true.
210  /// \param median The median value of the array, returned as the same
211  /// type as the array.
212  /// \param madfm The median absolute deviation from the median value
213  /// of the array, returned as the same type as the array.
214
215  int goodSize=0;
216  for(int i=0;i<size;i++) if(mask[i]) goodSize++;
217  if(goodSize==0){
218    std::cerr << "Error in findMedianStats: no good values!\n";
219    return;
220  }
221  T *newarray = new T[goodSize];
222  goodSize=0;
223  for(int i=0;i<size;i++) if(mask[i]) newarray[goodSize++] = array[i];
224  std::sort(newarray,newarray+goodSize);
225  if((goodSize%2)==0)
226    median = (newarray[goodSize/2-1]+newarray[goodSize/2])/2;
227  else
228    median = newarray[goodSize/2];
229
230  for(int i=0;i<goodSize;i++) newarray[i] = absval(newarray[i]-median);
231  std::sort(newarray,newarray+goodSize);
232  if((goodSize%2)==0)
233    madfm = (newarray[goodSize/2-1]+newarray[goodSize/2])/2;
234  else
235    madfm = newarray[goodSize/2];
236
237  delete [] newarray;
238}
239template void findMedianStats<int>(int *array, int size, bool *mask,
240                                      int &median, int &madfm);
241template void findMedianStats<long>(long *array, int size, bool *mask,
242                                       long &median, long &madfm);
243template void findMedianStats<float>(float *array, int size, bool *mask,
244                                        float &median, float &madfm);
245template void findMedianStats<double>(double *array, int size, bool *mask,
246                                         double &median, double &madfm);
247//--------------------------------------------------------------------
248 
249
250template <class T> void findNormalStats(T *array, int size,
251                                        float &mean, float &stddev)
252{
253  /// @details
254  /// Find the mean and rms or standard deviation of an array of
255  /// numbers. Type independent.
256  ///
257  /// \param array The array of numbers.
258  /// \param size The length of the array.
259  /// \param mean The mean value of the array, returned as a float.
260  /// \param stddev The rms or standard deviation of the array,
261  /// returned as a float.
262
263  if(size==0){
264    std::cerr << "Error in findNormalStats: zero sized array!\n";
265    return;
266  }
267  mean = array[0];
268  for(int i=1;i<size;i++){
269    mean += array[i];
270  }
271  mean /= float(size);
272
273  stddev = (array[0]-mean) * (array[0]-mean);
274  for(int i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
275  stddev = sqrt(stddev/float(size-1));
276
277}
278template void findNormalStats<int>(int *array, int size,
279                                      float &mean, float &stddev);
280template void findNormalStats<long>(long *array, int size,
281                                       float &mean, float &stddev);
282template void findNormalStats<float>(float *array, int size,
283                                        float &mean, float &stddev);
284template void findNormalStats<double>(double *array, int size,
285                                         float &mean, float &stddev);
286//--------------------------------------------------------------------
287
288template <class T> void findNormalStats(T *array, int size, bool *mask,
289                                        float &mean, float &stddev)
290{
291  /// @details
292  /// Find the mean and rms or standard deviation of a subset of an
293  /// array of numbers. The subset is defined by an array of bool
294  /// variables. Type independent.
295  ///
296  /// \param array The array of numbers.
297  /// \param size The length of the array.
298  /// \param mask An array of the same length that says whether to
299  /// include each member of the array in the calculations. Only look
300  /// at values where mask=true.
301  /// \param mean The mean value of the array, returned as a float.
302  /// \param stddev The rms or standard deviation of the array,
303  /// returned as a float.
304
305  int goodSize=0;
306  for(int i=0;i<size;i++) if(mask[i]) goodSize++;
307  if(goodSize==0){
308    std::cerr << "Error in findNormalStats: no good values!\n";
309    return;
310  }
311  int start=0;
312  while(!mask[start]){start++;}
313  mean = array[start];
314  for(int i=start+1;i<size;i++){
315    if(mask[i]) mean += array[i];
316  }
317  mean /= float(goodSize);
318
319  stddev = (array[start]-mean) * (array[start]-mean);
320  for(int i=1;i<size;i++){
321    if(mask[i]) stddev += (array[i]-mean)*(array[i]-mean);
322  }
323  stddev = sqrt(stddev/float(goodSize-1));
324
325}
326template void findNormalStats<int>(int *array, int size, bool *mask,
327                                      float &mean, float &stddev);
328template void findNormalStats<long>(long *array, int size, bool *mask,
329                                       float &mean, float &stddev);
330template void findNormalStats<float>(float *array, int size, bool *mask,
331                                        float &mean, float &stddev);
332template void findNormalStats<double>(double *array, int size, bool *mask,
333                                         float &mean, float &stddev);
334//--------------------------------------------------------------------
335//--------------------------------------------------------------------
336 
337
338template <class T> void findAllStats(T *array, int size,
339                                     float &mean, float &stddev,
340                                     T &median, T &madfm)
341{
342  /// @details
343  /// Find the mean,rms (or standard deviation), median AND madfm of an
344  /// array of numbers. Type independent.
345  ///
346  /// \param array The array of numbers.
347  /// \param size The length of the array.
348  /// \param mean The mean value of the array, returned as a float.
349  /// \param stddev The rms or standard deviation of the array,
350  /// returned as a float.
351  /// \param median The median value of the array, returned as the same
352  /// type as the array.
353  /// \param madfm The median absolute deviation from the median value
354  /// of the array, returned as the same type as the array.
355
356  if(size==0){
357    std::cerr << "Error in findAllStats: zero sized array!\n";
358    return;
359  }
360
361  T *newarray = new T[size];
362
363  for(int i=0;i<size;i++) newarray[i] = array[i];
364
365  mean = array[0];
366  for(int i=1;i<size;i++) mean += array[i];
367  mean /= float(size);
368
369  stddev = (array[0]-mean) * (array[0]-mean);
370  for(int i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
371  stddev = sqrt(stddev/float(size-1));
372
373  std::sort(newarray,newarray+size);
374  if((size%2)==0) median = (newarray[size/2-1]+newarray[size/2])/2;
375  else median = newarray[size/2];
376
377  for(int i=0;i<size;i++) newarray[i] = absval(newarray[i]-median);
378  std::sort(newarray,newarray+size);
379  if((size%2)==0) madfm = (newarray[size/2-1]+newarray[size/2])/2;
380  else madfm = newarray[size/2];
381
382  delete [] newarray;
383
384}
385template void findAllStats<int>(int *array, int size,
386                                float &mean, float &stddev,
387                                int &median, int &madfm);
388template void findAllStats<long>(long *array, int size,
389                                 float &mean, float &stddev,
390                                 long &median, long &madfm);
391template void findAllStats<float>(float *array, int size,
392                                  float &mean, float &stddev,
393                                  float &median, float &madfm);
394template void findAllStats<double>(double *array, int size,
395                                   float &mean, float &stddev,
396                                   double &median, double &madfm);
397//--------------------------------------------------------------------
398
399template <class T> void findAllStats(T *array, int size, bool *mask,
400                                     float &mean, float &stddev,
401                                     T &median, T &madfm)
402{
403  /// @details
404  /// Find the mean,rms (or standard deviation), median AND madfm of a
405  /// subset of an array of numbers. Type independent.The subset is
406  /// defined by an array of bool variables. Type independent.
407  ///
408  /// \param array The array of numbers.
409  /// \param size The length of the array.
410  /// \param mask An array of the same length that says whether to
411  /// include each member of the array in the calculations. Only look
412  /// at values where mask=true.
413  /// \param mean The mean value of the array, returned as a float.
414  /// \param stddev The rms or standard deviation of the array,
415  /// returned as a float.
416  /// \param median The median value of the array, returned as the same
417  /// type as the array.
418  /// \param madfm The median absolute deviation from the median value
419  /// of the array, returned as the same type as the array.
420
421  int goodSize=0;
422  for(int i=0;i<size;i++) if(mask[i]) goodSize++;
423  if(goodSize==0){
424    std::cerr << "Error in findAllStats: no good values!\n";
425    return;
426  }
427
428  T *newarray = new T[goodSize];
429  goodSize=0;
430  for(int i=0;i<size;i++) if(mask[i]) newarray[goodSize++] = array[i];
431
432  mean = 0.;
433  for(int i=0;i<goodSize;i++) mean += newarray[i];
434  mean /= float(goodSize);
435
436  stddev = 0.;
437  for(int i=0;i<goodSize;i++) stddev += (newarray[i]-mean)*(newarray[i]-mean);
438  stddev = sqrt(stddev/float(goodSize-1));
439
440  std::sort(newarray,newarray+goodSize);
441  if((goodSize%2)==0) median = (newarray[goodSize/2-1]+newarray[goodSize/2])/2;
442  else median = newarray[goodSize/2];
443
444  for(int i=0;i<goodSize;i++) newarray[i] = absval(newarray[i]-median);
445  std::sort(newarray,newarray+goodSize);
446  if((goodSize%2)==0) madfm = (newarray[goodSize/2-1]+newarray[goodSize/2])/2;
447  else madfm = newarray[goodSize/2];
448
449  delete [] newarray;
450
451}
452template void findAllStats<int>(int *array, int size, bool *mask,
453                                float &mean, float &stddev,
454                                int &median, int &madfm);
455template void findAllStats<long>(long *array, int size, bool *mask,
456                                 float &mean, float &stddev,
457                                 long &median, long &madfm);
458template void findAllStats<float>(float *array, int size, bool *mask,
459                                  float &mean, float &stddev,
460                                  float &median, float &madfm);
461template void findAllStats<double>(double *array, int size, bool *mask,
462                                   float &mean, float &stddev,
463                                   double &median, double &madfm);
464//--------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.