// ----------------------------------------------------------------------- // getStats.cc: Basic functions to calculate statistical parameters // such as mean, median, rms, madfm, min, max. // ----------------------------------------------------------------------- // Copyright (C) 2006, Matthew Whiting, ATNF // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. // // Duchamp is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License // along with Duchamp; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA // // Correspondence concerning Duchamp may be directed to: // Internet email: Matthew.Whiting [at] atnf.csiro.au // Postal address: Dr. Matthew Whiting // Australia Telescope National Facility, CSIRO // PO Box 76 // Epping NSW 1710 // AUSTRALIA // ----------------------------------------------------------------------- #include #include #include #include template T absval(T value) { /// Type-independent way of getting the absolute value. if( value > 0) return value; else return 0-value; } template int absval(int value); template long absval(long value); template float absval(float value); template double absval(double value); //-------------------------------------------------------------------- template void findMinMax(const T *array, const int size, T &min, T &max) { /// @details /// A function to find the minimum and maximum values of a set of numbers. /// \param array The array of data values. Type independent. /// \param size The length of the array /// \param min The returned value of the minimum value in the array. /// \param max The returned value of the maximum value in the array. min = max = array[0]; for(int i=1;imax) max=array[i]; } } template void findMinMax(const int *array, const int size, int &min, int &max); template void findMinMax(const long *array, const int size, long &min, long &max); template void findMinMax(const float *array, const int size, float &min, float &max); template void findMinMax(const double *array, const int size, double &min, double &max); //-------------------------------------------------------------------- template float findMean(T *array, int size) { /// @details /// Find the mean of an array of numbers. Type independent. /// \param array The array of numbers. /// \param size The length of the array. /// \return The mean value of the array, returned as a float double mean = double(array[0]); for(int i=1;i(int *array, int size); template float findMean(long *array, int size); template float findMean(float *array, int size); template float findMean(double *array, int size); //-------------------------------------------------------------------- template float findStddev(T *array, int size) { /// @details /// Find the rms or standard deviation of an array of numbers. Type independent. /// \param array The array of numbers. /// \param size The length of the array. /// \return The rms value of the array, returned as a float double mean = double(findMean(array,size)); double stddev = (double(array[0])-mean) * (double(array[0])-mean); for(int i=1;i(int *array, int size); template float findStddev(long *array, int size); template float findStddev(float *array, int size); template float findStddev(double *array, int size); //-------------------------------------------------------------------- template T findMedian(T *array, int size, bool changeArray) { /// @details /// Find the median value of an array of numbers. Type independent. /// \param array The array of numbers. /// \param size The length of the array. /// \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). /// \return The median value of the array, returned as the same type as the array. T *newarray; if(changeArray) newarray = array; else{ newarray = new T[size]; for(int i=0;i(int *array, int size, bool changeArray); template long findMedian(long *array, int size, bool changeArray); template float findMedian(float *array, int size, bool changeArray); template double findMedian(double *array, int size, bool changeArray); //-------------------------------------------------------------------- template T findMADFM(T *array, int size, bool changeArray) { /// @details /// Find the median absolute deviation from the median value of an /// array of numbers. Type independent. /// /// \param array The array of numbers. /// \param size The length of the array. /// \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. /// \return The median absolute deviation from the median value of /// the array, returned as the same type as the array. T *newarray; if(changeArray) newarray = array; else newarray = new T[size]; T median = findMedian(array,size,changeArray); T madfm; bool isEven = ((size/2)==0); for(int i=0;i(int *array, int size, bool changeArray); template long findMADFM(long *array, int size, bool changeArray); template float findMADFM(float *array, int size, bool changeArray); template double findMADFM(double *array, int size, bool changeArray); //-------------------------------------------------------------------- template T findMADFM(T *array, int size, T median, bool changeArray) { /// @details /// Find the median absolute deviation from the median value of an /// array of numbers. Type independent. This version accepts a previously- /// calculated median value. /// /// \param array The array of numbers. /// \param size The length of the array. /// \param median The median of the array. /// \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. /// \return The median absolute deviation from the median value of /// the array, returned as the same type as the array. T *newarray; if(changeArray) newarray = array; else newarray = new T[size]; T madfm; bool isEven = ((size/2)==0); for(int i=0;i(int *array, int size, int median, bool changeArray); template long findMADFM(long *array, int size, long median, bool changeArray); template float findMADFM(float *array, int size, float median, bool changeArray); template double findMADFM(double *array, int size, double median, bool changeArray); //-------------------------------------------------------------------- template void findMedianStats(T *array, int size, T &median, T &madfm) { /// @details /// Find the median and the median absolute deviation from the median /// value of an array of numbers. Type independent. /// /// \param array The array of numbers. /// \param size The length of the array. /// \param median The median value of the array, returned as the same /// type as the array. /// \param madfm The median absolute deviation from the median value /// of the array, returned as the same type as the array. if(size==0){ std::cerr << "Error in findMedianStats: zero sized array!\n"; return; } T *newarray = new T[size]; for(int i=0;i(int *array, int size, int &median, int &madfm); template void findMedianStats(long *array, int size, long &median, long &madfm); template void findMedianStats(float *array, int size, float &median, float &madfm); template void findMedianStats(double *array, int size, double &median, double &madfm); //-------------------------------------------------------------------- template void findMedianStats(T *array, int size, bool *mask, T &median, T &madfm) { /// @details /// Find the median and the median absolute deviation from the median /// value of a subset of an array of numbers. The subset is defined /// by an array of bool variables. Type independent. /// /// \param array The array of numbers. /// \param size The length of the array. /// \param mask An array of the same length that says whether to /// include each member of the array in the calculations. Only use /// values where mask=true. /// \param median The median value of the array, returned as the same /// type as the array. /// \param madfm The median absolute deviation from the median value /// of the array, returned as the same type as the array. int goodSize=0; for(int i=0;i(int *array, int size, bool *mask, int &median, int &madfm); template void findMedianStats(long *array, int size, bool *mask, long &median, long &madfm); template void findMedianStats(float *array, int size, bool *mask, float &median, float &madfm); template void findMedianStats(double *array, int size, bool *mask, double &median, double &madfm); //-------------------------------------------------------------------- template void findNormalStats(T *array, int size, float &mean, float &stddev) { /// @details /// Find the mean and rms or standard deviation of an array of /// numbers. Type independent. /// /// \param array The array of numbers. /// \param size The length of the array. /// \param mean The mean value of the array, returned as a float. /// \param stddev The rms or standard deviation of the array, /// returned as a float. if(size==0){ std::cerr << "Error in findNormalStats: zero sized array!\n"; return; } mean = array[0]; for(int i=1;i(int *array, int size, float &mean, float &stddev); template void findNormalStats(long *array, int size, float &mean, float &stddev); template void findNormalStats(float *array, int size, float &mean, float &stddev); template void findNormalStats(double *array, int size, float &mean, float &stddev); //-------------------------------------------------------------------- template void findNormalStats(T *array, int size, bool *mask, float &mean, float &stddev) { /// @details /// Find the mean and rms or standard deviation of a subset of an /// array of numbers. The subset is defined by an array of bool /// variables. Type independent. /// /// \param array The array of numbers. /// \param size The length of the array. /// \param mask An array of the same length that says whether to /// include each member of the array in the calculations. Only look /// at values where mask=true. /// \param mean The mean value of the array, returned as a float. /// \param stddev The rms or standard deviation of the array, /// returned as a float. int goodSize=0; for(int i=0;i(int *array, int size, bool *mask, float &mean, float &stddev); template void findNormalStats(long *array, int size, bool *mask, float &mean, float &stddev); template void findNormalStats(float *array, int size, bool *mask, float &mean, float &stddev); template void findNormalStats(double *array, int size, bool *mask, float &mean, float &stddev); //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void findAllStats(T *array, int size, float &mean, float &stddev, T &median, T &madfm) { /// @details /// Find the mean,rms (or standard deviation), median AND madfm of an /// array of numbers. Type independent. /// /// \param array The array of numbers. /// \param size The length of the array. /// \param mean The mean value of the array, returned as a float. /// \param stddev The rms or standard deviation of the array, /// returned as a float. /// \param median The median value of the array, returned as the same /// type as the array. /// \param madfm The median absolute deviation from the median value /// of the array, returned as the same type as the array. if(size==0){ std::cerr << "Error in findAllStats: zero sized array!\n"; return; } T *newarray = new T[size]; for(int i=0;i(int *array, int size, float &mean, float &stddev, int &median, int &madfm); template void findAllStats(long *array, int size, float &mean, float &stddev, long &median, long &madfm); template void findAllStats(float *array, int size, float &mean, float &stddev, float &median, float &madfm); template void findAllStats(double *array, int size, float &mean, float &stddev, double &median, double &madfm); //-------------------------------------------------------------------- template void findAllStats(T *array, int size, bool *mask, float &mean, float &stddev, T &median, T &madfm) { /// @details /// Find the mean,rms (or standard deviation), median AND madfm of a /// subset of an array of numbers. Type independent.The subset is /// defined by an array of bool variables. Type independent. /// /// \param array The array of numbers. /// \param size The length of the array. /// \param mask An array of the same length that says whether to /// include each member of the array in the calculations. Only look /// at values where mask=true. /// \param mean The mean value of the array, returned as a float. /// \param stddev The rms or standard deviation of the array, /// returned as a float. /// \param median The median value of the array, returned as the same /// type as the array. /// \param madfm The median absolute deviation from the median value /// of the array, returned as the same type as the array. int goodSize=0; for(int i=0;i(int *array, int size, bool *mask, float &mean, float &stddev, int &median, int &madfm); template void findAllStats(long *array, int size, bool *mask, float &mean, float &stddev, long &median, long &madfm); template void findAllStats(float *array, int size, bool *mask, float &mean, float &stddev, float &median, float &madfm); template void findAllStats(double *array, int size, bool *mask, float &mean, float &stddev, double &median, double &madfm); //--------------------------------------------------------------------