source: trunk/src/Utils/getStats.cc @ 847

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

New stats functions to find the stats of difference arrays, and to better find statistics in masked arrays. Also moving to size_t etc for the sizes.

File size: 32.8 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 size_t 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(size_t 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 size_t size,
62                                 int &min, int &max);
63template void findMinMax<long>(const long *array, const size_t size,
64                                  long &min, long &max);
65template void findMinMax<float>(const float *array, const size_t size,
66                                   float &min, float &max);
67template void findMinMax<double>(const double *array, const size_t size,
68                                    double &min, double &max);
69//--------------------------------------------------------------------
70
71template <class T> float findMean(T *array, size_t 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  double mean = 0;
79  for(size_t i=0;i<size;i++) mean += double(array[i]);
80  if(size>0)
81    mean /= double(size);
82  return float(mean);
83}
84template float findMean<int>(int *array, size_t size);
85template float findMean<long>(long *array, size_t size);
86template float findMean<float>(float *array, size_t size);
87template float findMean<double>(double *array, size_t size);
88//--------------------------------------------------------------------
89
90template <class T> float findMean(T *array, bool *mask, size_t size)
91{
92  /// @details
93  /// Find the mean of an array of numbers. Type independent.
94  /// \param array The array of numbers.
95  /// \param mask An array of the same length that says whether to
96  /// include each member of the array in the calculations. Only use
97  /// values where mask=true.
98  /// \param size The length of the array.
99  /// \return The mean value of the array, returned as a float
100  double mean = 0.;
101  int ct=0;
102  for(size_t i=0;i<size;i++){
103    if(mask[i]){
104      mean += double(array[i]);
105      ct++;
106    }
107  }
108  if(ct>0) mean /= double(ct);
109  return float(mean);
110}
111template float findMean<int>(int *array, bool *mask, size_t size);
112template float findMean<long>(long *array, bool *mask, size_t size);
113template float findMean<float>(float *array, bool *mask, size_t size);
114template float findMean<double>(double *array, bool *mask, size_t size);
115//--------------------------------------------------------------------
116
117template <class T> float findStddev(T *array, size_t size)
118{
119  /// @details Find the rms or standard deviation of an array of
120  /// numbers. Type independent. Calculated by iterating only once,
121  /// using \sum x and \sum x^2 (no call to findMean)
122  /// \param array The array of numbers.
123  /// \param size The length of the array.
124  /// \return The rms value of the array, returned as a float
125
126  // double mean = double(findMean(array,size));
127  // double stddev = (double(array[0])-mean) * (double(array[0])-mean);
128  // for(size_t i=1;i<size;i++) stddev += (double(array[i])-mean)*(double(array[i])-mean);
129  // double stddev = stddev/double(size-1));
130
131  T sumx=0,sumxx=0;
132  double stddev=0;
133  for(size_t i=0;i<size;i++){
134    sumx += array[i];
135    sumxx += (array[i]*array[i]);
136  }
137  if(size>0)
138    stddev = sqrt(double(sumxx)/double(size) - double(sumx*sumx)/double(size*size));
139  return float(stddev);
140}
141template float findStddev<int>(int *array, size_t size);
142template float findStddev<long>(long *array, size_t size);
143template float findStddev<float>(float *array, size_t size);
144template float findStddev<double>(double *array, size_t size);
145//--------------------------------------------------------------------
146
147template <class T> float findStddev(T *array, bool *mask, size_t size)
148{
149  /// @details Find the rms or standard deviation of an array of
150  /// numbers. Type independent. Calculated by iterating only once,
151  /// using \sum x and \sum x^2 (no call to findMean)
152  /// \param array The array of numbers.
153  /// \param mask An array of the same length that says whether to
154  /// include each member of the array in the calculations. Only use
155  /// values where mask=true.
156  /// \param size The length of the array.
157  /// \return The rms value of the array, returned as a float
158
159  T sumx=0,sumxx=0;
160  double stddev=0;
161  int ct=0;
162  for(size_t i=0;i<size;i++){
163    if(mask[i]){
164      sumx += array[i];
165      sumxx += (array[i]*array[i]);
166      ct++;
167    }
168  }
169  if(ct>0)
170    stddev = sqrt(double(sumxx)/double(ct) - double(sumx*sumx)/double(ct*ct));
171  return float(stddev);
172}
173template float findStddev<int>(int *array, bool *mask, size_t size);
174template float findStddev<long>(long *array, bool *mask, size_t size);
175template float findStddev<float>(float *array, bool *mask, size_t size);
176template float findStddev<double>(double *array, bool *mask, size_t size);
177//--------------------------------------------------------------------
178
179template <class T> T findMedian(T *array, size_t size, bool changeArray)
180{
181  /// @details
182  /// Find the median value of an array of numbers. Type independent.
183  /// \param array The array of numbers.
184  /// \param size The length of the array.
185  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered (ie. the order of elements will be changed).
186  /// \return The median value of the array, returned as the same type as the array.
187  T *newarray;
188  if(changeArray) newarray = array;
189  else{
190    newarray = new T[size];
191    for(size_t i=0;i<size;i++) newarray[i] = array[i];
192  }
193  T median;
194  bool isEven = ((size%2)==0);
195  std::nth_element(newarray,newarray+size/2,newarray+size);
196  median = newarray[size/2];
197  if(isEven){
198    std::nth_element(newarray,newarray+size/2-1,newarray+size);
199    median += newarray[size/2-1];
200    median /= T(2);
201  }
202  if(!changeArray) delete [] newarray;
203  return median;
204}
205template int findMedian<int>(int *array, size_t size, bool changeArray);
206template long findMedian<long>(long *array, size_t size, bool changeArray);
207template float findMedian<float>(float *array, size_t size, bool changeArray);
208template double findMedian<double>(double *array, size_t size, bool changeArray);
209//--------------------------------------------------------------------
210
211template <class T> T findMedian(T *array, bool *mask, size_t size)
212{
213  /// @details
214  /// Find the median value of an array of numbers. Type independent.
215  /// \param array The array of numbers.
216  /// \param size The length of the array.
217  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered (ie. the order of elements will be changed).
218  /// \return The median value of the array, returned as the same type as the array.
219
220  int goodSize=0,ct=0;
221  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
222  T *newarray = new T[goodSize];
223  for(size_t i=0;i<size;i++) {
224    if(mask[i]) newarray[ct++] = array[i];
225  }
226  T median;
227  bool isEven = ((goodSize%2)==0);
228  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
229  median = newarray[goodSize/2];
230  if(isEven){
231    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
232    median += newarray[goodSize/2-1];
233    median /= T(2);
234  }
235  delete [] newarray;
236  return median;
237}
238template int findMedian<int>(int *array, bool *mask, size_t size);
239template long findMedian<long>(long *array, bool *mask, size_t size);
240template float findMedian<float>(float *array, bool *mask, size_t size);
241template double findMedian<double>(double *array, bool *mask, size_t size);
242//--------------------------------------------------------------------
243
244template <class T> T findMADFM(T *array, size_t size, bool changeArray)
245{
246  /// @details
247  /// Find the median absolute deviation from the median value of an
248  /// array of numbers. Type independent.
249  ///
250  /// \param array The array of numbers.
251  /// \param size The length of the array.
252  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
253  /// \return The median absolute deviation from the median value of
254  /// the array, returned as the same type as the array.
255  T *newarray;
256  if(changeArray) newarray = array;
257  else newarray = new T[size];
258
259  T median = findMedian<T>(array,size,changeArray);
260  T madfm;
261  bool isEven = ((size%2)==0);
262  for(size_t i=0;i<size;i++) newarray[i] = absval(array[i]-median);
263  std::nth_element(newarray,newarray+size/2,newarray+size);
264  madfm = newarray[size/2];
265  if(isEven){
266    std::nth_element(newarray,newarray+size/2-1,newarray+size);
267    madfm += newarray[size/2-1];
268    madfm /= T(2);
269  }
270  if(!changeArray) delete [] newarray;
271  return madfm;
272}
273template int findMADFM<int>(int *array, size_t size, bool changeArray);
274template long findMADFM<long>(long *array, size_t size, bool changeArray);
275template float findMADFM<float>(float *array, size_t size, bool changeArray);
276template double findMADFM<double>(double *array, size_t size, bool changeArray);
277//--------------------------------------------------------------------
278
279template <class T> T findMADFM(T *array, bool *mask, size_t size)
280{
281  /// @details
282  /// Find the median absolute deviation from the median value of an
283  /// array of numbers. Type independent.
284  ///
285  /// \param array The array of numbers.
286  /// \param size The length of the array.
287  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
288  /// \return The median absolute deviation from the median value of
289  /// the array, returned as the same type as the array.
290  T median = findMedian<T>(array,mask,size);
291  int goodSize=0,ct=0;
292  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
293  T *newarray = new T[goodSize];
294  for(size_t i=0;i<size;i++)
295    if(mask[i]) newarray[ct++] = absval(array[i]-median);
296
297  T madfm;
298  bool isEven = ((goodSize%2)==0);
299  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
300  madfm = newarray[goodSize/2];
301  if(isEven){
302    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
303    madfm += newarray[goodSize/2-1];
304    madfm /= T(2);
305  }
306  delete [] newarray;
307  return madfm;
308}
309template int findMADFM<int>(int *array, bool *mask, size_t size);
310template long findMADFM<long>(long *array, bool *mask, size_t size);
311template float findMADFM<float>(float *array, bool *mask, size_t size);
312template double findMADFM<double>(double *array, bool *mask, size_t size);
313//--------------------------------------------------------------------
314
315template <class T> T findMADFM(T *array, size_t size, T median, bool changeArray)
316{
317  /// @details
318  /// Find the median absolute deviation from the median value of an
319  /// array of numbers. Type independent. This version accepts a previously-
320  /// calculated median value.
321  ///
322  /// \param array The array of numbers.
323  /// \param size The length of the array.
324  /// \param median The median of the array.
325  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
326  /// \return The median absolute deviation from the median value of
327  /// the array, returned as the same type as the array.
328  T *newarray;
329  if(changeArray) newarray = array;
330  else newarray = new T[size];
331
332  T madfm;
333  bool isEven = ((size%2)==0);
334  for(size_t i=0;i<size;i++) newarray[i] = absval(array[i]-median);
335  std::nth_element(newarray,newarray+size/2,newarray+size);
336  madfm = newarray[size/2];
337  if(isEven){
338    std::nth_element(newarray,newarray+size/2-1,newarray+size);
339    madfm += newarray[size/2-1];
340    madfm /= T(2);
341  }
342  if(!changeArray) delete [] newarray;
343  return madfm;
344}
345template int findMADFM<int>(int *array, size_t size, int median, bool changeArray);
346template long findMADFM<long>(long *array, size_t size, long median, bool changeArray);
347template float findMADFM<float>(float *array, size_t size, float median, bool changeArray);
348template double findMADFM<double>(double *array, size_t size, double median, bool changeArray);
349//--------------------------------------------------------------------
350
351template <class T> T findMADFM(T *array, bool *mask, size_t size, T median)
352{
353  /// @details
354  /// Find the median absolute deviation from the median value of an
355  /// array of numbers. Type independent. This version accepts a previously-
356  /// calculated median value.
357  ///
358  /// \param array The array of numbers.
359  /// \param size The length of the array.
360  /// \param median The median of the array.
361  /// \param changeArray [false] Whether to use the provided array in calculations. If true, the input array will be altered - both the order and values of the elements will be changed.
362  /// \return The median absolute deviation from the median value of
363  /// the array, returned as the same type as the array.
364  int goodSize=0,ct=0;
365  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
366  T *newarray = new T[goodSize];
367  for(size_t i=0;i<size;i++){
368    if(mask[i]) newarray[ct++] = absval(array[i]-median);
369  }
370  T madfm;
371  bool isEven = ((goodSize%2)==0);
372  std::nth_element(newarray,newarray+goodSize/2,newarray+goodSize);
373  madfm = newarray[goodSize/2];
374  if(isEven){
375    std::nth_element(newarray,newarray+goodSize/2-1,newarray+goodSize);
376    madfm += newarray[goodSize/2-1];
377    madfm /= T(2);
378  }
379  delete [] newarray;
380  return madfm;
381}
382template int findMADFM<int>(int *array, bool *mask, size_t size, int median);
383template long findMADFM<long>(long *array, bool *mask, size_t size, long median);
384template float findMADFM<float>(float *array, bool *mask, size_t size, float median);
385template double findMADFM<double>(double *array, bool *mask, size_t size, double median);
386//--------------------------------------------------------------------
387
388template <class T> void findMedianStats(T *array, size_t size,
389                                        T &median, T &madfm)
390{
391  /// @details
392  /// Find the median and the median absolute deviation from the median
393  /// value of an array of numbers. Type independent.
394  ///
395  /// \param array The array of numbers.
396  /// \param size The length of the array.
397  /// \param median The median value of the array, returned as the same
398  /// type as the array.
399  /// \param madfm The median absolute deviation from the median value
400  /// of the array, returned as the same type as the array.
401  if(size==0){
402    std::cerr << "Error in findMedianStats: zero sized array!\n";
403    return;
404  }
405  T *newarray = new T[size];
406   for(size_t i=0;i<size;i++) newarray[i] = array[i];
407
408   median = findMedian(newarray,size,true);
409   //   madfm = findMADFM(newarray,size,true);
410   madfm = findMADFM(newarray,size,median,true);
411
412  delete [] newarray;
413}
414template void findMedianStats<int>(int *array, size_t size,
415                                      int &median, int &madfm);
416template void findMedianStats<long>(long *array, size_t size,
417                                       long &median, long &madfm);
418template void findMedianStats<float>(float *array, size_t size,
419                                        float &median, float &madfm);
420template void findMedianStats<double>(double *array, size_t size,
421                                         double &median, double &madfm);
422//--------------------------------------------------------------------
423
424template <class T> void findMedianStats(T *array, size_t size, bool *mask,
425                                        T &median, T &madfm)
426{
427  /// @details
428  /// Find the median and the median absolute deviation from the median
429  /// value of a subset of an array of numbers. The subset is defined
430  /// by an array of bool variables. Type independent.
431  ///
432  /// \param array The array of numbers.
433  /// \param size The length of the array.
434  /// \param mask An array of the same length that says whether to
435  /// include each member of the array in the calculations. Only use
436  /// values where mask=true.
437  /// \param median The median value of the array, returned as the same
438  /// type as the array.
439  /// \param madfm The median absolute deviation from the median value
440  /// of the array, returned as the same type as the array.
441
442  int goodSize=0;
443  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
444  if(goodSize==0){
445    std::cerr << "Error in findMedianStats: no good values!\n";
446    return;
447  }
448  T *newarray = new T[goodSize];
449
450  goodSize=0;
451  for(size_t i=0;i<size;i++) if(mask[i]) newarray[goodSize++] = array[i];
452  median = findMedian(newarray,goodSize,true);
453  //  madfm = findMADFM(newarray,goodSize,true);
454  madfm = findMADFM(newarray,goodSize,median,true);
455
456  delete [] newarray;
457}
458template void findMedianStats<int>(int *array, size_t size, bool *mask,
459                                      int &median, int &madfm);
460template void findMedianStats<long>(long *array, size_t size, bool *mask,
461                                       long &median, long &madfm);
462template void findMedianStats<float>(float *array, size_t size, bool *mask,
463                                        float &median, float &madfm);
464template void findMedianStats<double>(double *array, size_t size, bool *mask,
465                                         double &median, double &madfm);
466//--------------------------------------------------------------------
467 
468
469template <class T> void findNormalStats(T *array, size_t size,
470                                        float &mean, float &stddev)
471{
472  /// @details
473  /// Find the mean and rms or standard deviation of an array of
474  /// numbers. Type independent.
475  ///
476  /// \param array The array of numbers.
477  /// \param size The length of the array.
478  /// \param mean The mean value of the array, returned as a float.
479  /// \param stddev The rms or standard deviation of the array,
480  /// returned as a float.
481
482  if(size==0){
483    std::cerr << "Error in findNormalStats: zero sized array!\n";
484    return;
485  }
486  mean = array[0];
487  for(size_t i=1;i<size;i++){
488    mean += array[i];
489  }
490  mean /= float(size);
491
492  stddev = (array[0]-mean) * (array[0]-mean);
493  for(size_t i=1;i<size;i++) stddev += (array[i]-mean)*(array[i]-mean);
494  stddev = sqrt(stddev/float(size-1));
495
496}
497template void findNormalStats<int>(int *array, size_t size,
498                                      float &mean, float &stddev);
499template void findNormalStats<long>(long *array, size_t size,
500                                       float &mean, float &stddev);
501template void findNormalStats<float>(float *array, size_t size,
502                                        float &mean, float &stddev);
503template void findNormalStats<double>(double *array, size_t size,
504                                         float &mean, float &stddev);
505//--------------------------------------------------------------------
506
507template <class T> void findNormalStats(T *array, size_t size, bool *mask,
508                                        float &mean, float &stddev)
509{
510  /// @details
511  /// Find the mean and rms or standard deviation of a subset of an
512  /// array of numbers. The subset is defined by an array of bool
513  /// variables. Type independent.
514  ///
515  /// \param array The array of numbers.
516  /// \param size The length of the array.
517  /// \param mask An array of the same length that says whether to
518  /// include each member of the array in the calculations. Only look
519  /// at values where mask=true.
520  /// \param mean The mean value of the array, returned as a float.
521  /// \param stddev The rms or standard deviation of the array,
522  /// returned as a float.
523
524  int goodSize=0;
525  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
526  if(goodSize==0){
527    std::cerr << "Error in findNormalStats: no good values!\n";
528    return;
529  }
530  int start=0;
531  while(!mask[start]){start++;}
532  mean = array[start];
533  for(size_t i=start+1;i<size;i++){
534    if(mask[i]) mean += array[i];
535  }
536  mean /= float(goodSize);
537
538  stddev = (array[start]-mean) * (array[start]-mean);
539  for(size_t i=1;i<size;i++){
540    if(mask[i]) stddev += (array[i]-mean)*(array[i]-mean);
541  }
542  stddev = sqrt(stddev/float(goodSize-1));
543
544}
545template void findNormalStats<int>(int *array, size_t size, bool *mask,
546                                      float &mean, float &stddev);
547template void findNormalStats<long>(long *array, size_t size, bool *mask,
548                                       float &mean, float &stddev);
549template void findNormalStats<float>(float *array, size_t size, bool *mask,
550                                        float &mean, float &stddev);
551template void findNormalStats<double>(double *array, size_t size, bool *mask,
552                                         float &mean, float &stddev);
553//--------------------------------------------------------------------
554//--------------------------------------------------------------------
555 
556
557template <class T> void findAllStats(T *array, size_t size,
558                                     float &mean, float &stddev,
559                                     T &median, T &madfm)
560{
561  /// @details
562  /// Find the mean,rms (or standard deviation), median AND madfm of an
563  /// array of numbers. Type independent.
564  ///
565  /// \param array The array of numbers.
566  /// \param size The length of the array.
567  /// \param mean The mean value of the array, returned as a float.
568  /// \param stddev The rms or standard deviation of the array,
569  /// returned as a float.
570  /// \param median The median value of the array, returned as the same
571  /// type as the array.
572  /// \param madfm The median absolute deviation from the median value
573  /// of the array, returned as the same type as the array.
574
575  if(size==0){
576    std::cerr << "Error in findAllStats: zero sized array!\n";
577    return;
578  }
579
580  T *newarray = new T[size];
581
582  for(size_t i=0;i<size;i++) newarray[i] = array[i];
583
584  mean = findMean(newarray,size);
585  stddev = findStddev(newarray,size);
586  median = findMedian(newarray,size,true);
587  //  madfm = findMADFM(newarray,size,true);
588  madfm = findMADFM(newarray,size,median,true);
589
590  delete [] newarray;
591
592}
593template void findAllStats<int>(int *array, size_t size,
594                                float &mean, float &stddev,
595                                int &median, int &madfm);
596template void findAllStats<long>(long *array, size_t size,
597                                 float &mean, float &stddev,
598                                 long &median, long &madfm);
599template void findAllStats<float>(float *array, size_t size,
600                                  float &mean, float &stddev,
601                                  float &median, float &madfm);
602template void findAllStats<double>(double *array, size_t size,
603                                   float &mean, float &stddev,
604                                   double &median, double &madfm);
605//--------------------------------------------------------------------
606
607template <class T> void findAllStats(T *array, size_t size, bool *mask,
608                                     float &mean, float &stddev,
609                                     T &median, T &madfm)
610{
611  /// @details
612  /// Find the mean,rms (or standard deviation), median AND madfm of a
613  /// subset of an array of numbers. Type independent.The subset is
614  /// defined by an array of bool variables. Type independent.
615  ///
616  /// \param array The array of numbers.
617  /// \param size The length of the array.
618  /// \param mask An array of the same length that says whether to
619  /// include each member of the array in the calculations. Only look
620  /// at values where mask=true.
621  /// \param mean The mean value of the array, returned as a float.
622  /// \param stddev The rms or standard deviation of the array,
623  /// returned as a float.
624  /// \param median The median value of the array, returned as the same
625  /// type as the array.
626  /// \param madfm The median absolute deviation from the median value
627  /// of the array, returned as the same type as the array.
628
629  int goodSize=0;
630  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
631  if(goodSize==0){
632    std::cerr << "Error in findAllStats: no good values!\n";
633    return;
634  }
635
636  T *newarray = new T[goodSize];
637  goodSize=0;
638  for(size_t i=0;i<size;i++) if(mask[i]) newarray[goodSize++] = array[i];
639
640  mean = findMean(newarray,goodSize);
641  stddev = findStddev(newarray,goodSize);
642  median = findMedian(newarray,goodSize,true);
643  //madfm = findMADFM(newarray,goodSize,true);
644  madfm = findMADFM(newarray,goodSize,median,true);
645
646  delete [] newarray;
647
648}
649template void findAllStats<int>(int *array, size_t size, bool *mask,
650                                float &mean, float &stddev,
651                                int &median, int &madfm);
652template void findAllStats<long>(long *array, size_t size, bool *mask,
653                                 float &mean, float &stddev,
654                                 long &median, long &madfm);
655template void findAllStats<float>(float *array, size_t size, bool *mask,
656                                  float &mean, float &stddev,
657                                  float &median, float &madfm);
658template void findAllStats<double>(double *array, size_t size, bool *mask,
659                                   float &mean, float &stddev,
660                                   double &median, double &madfm);
661//--------------------------------------------------------------------
662template <class T> void findMedianStatsDiff(T *first, T *second, size_t size,
663                                            T &median, T &madfm)
664{
665  /// @details Find the median and the median absolute deviation from
666  /// the median value of the difference between two arrays of
667  /// numbers. Type independent. The difference is defined as first -
668  /// second.
669  ///
670  /// \param first The first array
671  /// \param second The second array
672  /// \param size The length of the array.
673  /// \param median The median value of the array, returned as the same
674  /// type as the array.
675  /// \param madfm The median absolute deviation from the median value
676  /// of the array, returned as the same type as the array.
677  if(size==0){
678    std::cerr << "Error in findMedianStats: zero sized array!\n";
679    return;
680  }
681  T *newarray = new T[size];
682   for(size_t i=0;i<size;i++) newarray[i] = first[i]-second[i];
683
684   median = findMedian(newarray,size,true);
685   //   madfm = findMADFM(newarray,size,true);
686   madfm = findMADFM(newarray,size,median,true);
687
688  delete [] newarray;
689}
690template void findMedianStatsDiff<int>(int *first, int *second, size_t size,
691                                       int &median, int &madfm);
692template void findMedianStatsDiff<long>(long *first, long *second, size_t size,
693                                        long &median, long &madfm);
694template void findMedianStatsDiff<float>(float *first, float *second, size_t size,
695                                         float &median, float &madfm);
696template void findMedianStatsDiff<double>(double *first, double *second, size_t size,
697                                          double &median, double &madfm);
698//--------------------------------------------------------------------
699
700template <class T> void findMedianStatsDiff(T *first, T *second, size_t size, bool *mask,
701                                            T &median, T &madfm)
702{
703  /// @details Find the median and the median absolute deviation from
704  /// the median value of the difference between two arrays of
705  /// numbers, where some elements are masked out. The mask is defined
706  /// by an array of bool variables. Type independent. The difference
707  /// is defined as first - second.
708  ///
709  /// \param first The first array
710  /// \param second The second array
711  /// \param size The length of the array.
712  /// \param mask An array of the same length that says whether to
713  /// include each member of the array in the calculations. Only use
714  /// values where mask=true.
715  /// \param median The median value of the array, returned as the same
716  /// type as the array.
717  /// \param madfm The median absolute deviation from the median value
718  /// of the array, returned as the same type as the array.
719
720  int goodSize=0;
721  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
722  if(goodSize==0){
723    std::cerr << "Error in findMedianStats: no good values!\n";
724    return;
725  }
726  T *newarray = new T[goodSize];
727
728  goodSize=0;
729  for(size_t i=0;i<size;i++) if(mask[i]) newarray[goodSize++] = first[i]-second[i];
730  median = findMedian(newarray,goodSize,true);
731  //  madfm = findMADFM(newarray,goodSize,true);
732  madfm = findMADFM(newarray,goodSize,median,true);
733
734  delete [] newarray;
735}
736template void findMedianStatsDiff<int>(int *first, int *second, size_t size, bool *mask,
737                                       int &median, int &madfm);
738template void findMedianStatsDiff<long>(long *first, long *second, size_t size, bool *mask,
739                                        long &median, long &madfm);
740template void findMedianStatsDiff<float>(float *first, float *second, size_t size, bool *mask,
741                                         float &median, float &madfm);
742template void findMedianStatsDiff<double>(double *first, double *second, size_t size, bool *mask,
743                                          double &median, double &madfm);
744//--------------------------------------------------------------------
745 
746
747template <class T> void findNormalStatsDiff(T *first, T *second, size_t size,
748                                            float &mean, float &stddev)
749{
750  /// @details
751  /// Find the mean and rms or standard deviation of  the difference between two arrays of
752  /// numbers. The difference is defined as first - second. Type independent.
753  ///
754  /// \param first The first array
755  /// \param second The second array
756  /// \param size The length of the array.
757  /// \param mean The mean value of the array, returned as a float.
758  /// \param stddev The rms or standard deviation of the array,
759  /// returned as a float.
760
761  if(size==0){
762    std::cerr << "Error in findNormalStats: zero sized array!\n";
763    return;
764  }
765  mean = first[0]-second[0];
766  for(size_t i=1;i<size;i++){
767    mean += (first[i]-second[i]);
768  }
769  mean /= float(size);
770
771  stddev = (first[0]-second[0]-mean) * (first[0]-second[0]-mean);
772  for(size_t i=1;i<size;i++) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
773  stddev = sqrt(stddev/float(size-1));
774
775}
776template void findNormalStatsDiff<int>(int *first, int *second, size_t size,
777                                       float &mean, float &stddev);
778template void findNormalStatsDiff<long>(long *first, long *second, size_t size,
779                                        float &mean, float &stddev);
780template void findNormalStatsDiff<float>(float *first, float *second, size_t size,
781                                         float &mean, float &stddev);
782template void findNormalStatsDiff<double>(double *first, double *second, size_t size,
783                                          float &mean, float &stddev);
784//--------------------------------------------------------------------
785
786template <class T> void findNormalStatsDiff(T *first, T *second, size_t size, bool *mask,
787                                            float &mean, float &stddev)
788{
789  /// @details Find the mean and rms or standard deviation of the
790  /// difference between two arrays of numbers, where some elements
791  /// are masked out. The mask is defined by an array of bool
792  /// variables, and the difference is defined as first - second. Type
793  /// independent.
794  ///
795  /// \param first The first array
796  /// \param second The second array
797  /// \param size The length of the array.
798  /// \param mask An array of the same length that says whether to
799  /// include each member of the array in the calculations. Only look
800  /// at values where mask=true.
801  /// \param mean The mean value of the array, returned as a float.
802  /// \param stddev The rms or standard deviation of the array,
803  /// returned as a float.
804
805  int goodSize=0;
806  for(size_t i=0;i<size;i++) if(mask[i]) goodSize++;
807  if(goodSize==0){
808    std::cerr << "Error in findNormalStats: no good values!\n";
809    return;
810  }
811  int start=0;
812  while(!mask[start]){start++;}
813  mean = first[start]-second[start];
814  for(size_t i=start+1;i<size;i++){
815    if(mask[i]) mean += (first[i]-second[i]);
816  }
817  mean /= float(goodSize);
818
819  stddev = (first[start]-second[start]-mean) * (first[start]-second[start]-mean);
820  for(size_t i=1;i<size;i++){
821    if(mask[i]) stddev += (first[i]-second[i]-mean)*(first[i]-second[i]-mean);
822  }
823  stddev = sqrt(stddev/float(goodSize-1));
824
825}
826template void findNormalStatsDiff<int>(int *first, int *second, size_t size, bool *mask,
827                                       float &mean, float &stddev);
828template void findNormalStatsDiff<long>(long *first, long *second, size_t size, bool *mask,
829                                        float &mean, float &stddev);
830template void findNormalStatsDiff<float>(float *first, float *second, size_t size, bool *mask,
831                                         float &mean, float &stddev);
832template void findNormalStatsDiff<double>(double *first, double *second, size_t size, bool *mask,
833                                          float &mean, float &stddev);
834//--------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.