source: tags/release-1.2.2/src/Utils/getNormalStats.cc

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

Removing unused, commented-out code

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 sumx=0.,sumxx=0.;
136  double stddev=0.;
137  double dsize=double(size);
138  for(size_t i=0;i<size;i++){
139    sumx += array[i];
140    sumxx += (array[i]*array[i]);
141  }
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;
145  if(size>0)
146    stddev = sqrt(sumxx/dsize - mean*mean);
147   // std::cerr << stddev << " " << float(stddev) << "\n";
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  double sumx=0.,sumxx=0.;
166  double stddev=0.;
167  double dsize=double(size);
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  }
172  double mean=sumx/dsize;
173  if(size>0)
174    stddev = sqrt(sumxx/dsize - mean*mean);
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
183template <class T> float findStddev(T *array, bool *mask, size_t size)
184{
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)
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.
192  /// \param size The length of the array.
193  /// \return The rms value of the array, returned as a float
194
195  double sumx=0.,sumxx=0.;
196  double stddev=0.;
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    }
204  }
205  double dct=double(ct);
206  double mean=sumx/dct;
207  if(ct>0)
208    stddev = sqrt(sumxx/dct - mean*mean);
209  return float(stddev);
210}
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);
215//--------------------------------------------------------------------
216
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
229  double sumx=0,sumxx=0;
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  }
239  double dct=double(ct);
240  double mean=sumx/dct;
241  if(ct>0)
242    stddev = sqrt(sumxx/dct - mean*mean);
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
251template <class T> void findNormalStats(T *array, size_t size,
252                                        float &mean, float &stddev)
253{
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
264  if(size==0){
265    std::cerr << "Error in findNormalStats: zero sized array!\n";
266    return;
267  }
268  mean = array[0];
269  for(size_t i=1;i<size;i++){
270    mean += array[i];
271  }
272  mean /= float(size);
273
274  stddev = (array[0]-mean) * (array[0]-mean);
275  for(size_t i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
276  stddev = sqrt(stddev/float(size-1));
277
278}
279template void findNormalStats<int>(int *array, size_t size,
280                                      float &mean, float &stddev);
281template void findNormalStats<long>(long *array, size_t size,
282                                       float &mean, float &stddev);
283template void findNormalStats<float>(float *array, size_t size,
284                                        float &mean, float &stddev);
285template void findNormalStats<double>(double *array, size_t size,
286                                         float &mean, float &stddev);
287//--------------------------------------------------------------------
288
289template <class T> void findNormalStats(T *array, size_t size, bool *mask,
290                                        float &mean, float &stddev)
291{
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
306  int goodSize=0;
307  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
308  if(goodSize==0){
309    std::cerr << "Error in findNormalStats: no good values!\n";
310    return;
311  }
312  int start=0;
313  while(!mask[start]){start++;}
314  mean = array[start];
315  for(size_t i=start+1;i<size;i++){
316    if(mask[i]) mean += array[i];
317  }
318  mean /= float(goodSize);
319
320  stddev = (array[start]-mean) * (array[start]-mean);
321  for(size_t i=1;i<size;i++){
322    if(mask[i]) stddev += (array[i]-mean)*(array[i]-mean);
323  }
324  stddev = sqrt(stddev/float(goodSize-1));
325
326}
327template void findNormalStats<int>(int *array, size_t size, bool *mask,
328                                      float &mean, float &stddev);
329template void findNormalStats<long>(long *array, size_t size, bool *mask,
330                                       float &mean, float &stddev);
331template void findNormalStats<float>(float *array, size_t size, bool *mask,
332                                        float &mean, float &stddev);
333template void findNormalStats<double>(double *array, size_t size, bool *mask,
334                                         float &mean, float &stddev);
335//-------------------------------------------------------------------- 
336
337template <class T> void findNormalStatsDiff(T *first, T *second, size_t size,
338                                            float &mean, float &stddev)
339{
340  /// @details
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.
343  ///
344  /// \param first The first array
345  /// \param second The second array
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
351  if(size==0){
352    std::cerr << "Error in findNormalStats: zero sized array!\n";
353    return;
354  }
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);
360
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));
364
365}
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);
374//--------------------------------------------------------------------
375
376template <class T> void findNormalStatsDiff(T *first, T *second, size_t size, bool *mask,
377                                            float &mean, float &stddev)
378{
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.
384  ///
385  /// \param first The first array
386  /// \param second The second array
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
395  int goodSize=0;
396  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
397  if(goodSize==0){
398    std::cerr << "Error in findNormalStats: no good values!\n";
399    return;
400  }
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);
408
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));
414
415}
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);
424//--------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.