// ----------------------------------------------------------------------- // 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 size_t 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(size_t i=1;imax) max=array[i]; } } template void findMinMax(const int *array, const size_t size, int &min, int &max); template void findMinMax(const long *array, const size_t size, long &min, long &max); template void findMinMax(const float *array, const size_t size, float &min, float &max); template void findMinMax(const double *array, const size_t size, double &min, double &max); //-------------------------------------------------------------------- template float findMean(T *array, size_t 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 = 0; for(size_t i=0;i0) mean /= double(size); return float(mean); } template float findMean(int *array, size_t size); template float findMean(long *array, size_t size); template float findMean(float *array, size_t size); template float findMean(double *array, size_t size); //-------------------------------------------------------------------- template float findMean(T *array, bool *mask, size_t size) { /// @details /// Find the mean of an array of numbers. Type independent. /// \param array The array of numbers. /// \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 size The length of the array. /// \return The mean value of the array, returned as a float double mean = 0.; int ct=0; for(size_t i=0;i0) mean /= double(ct); return float(mean); } template float findMean(int *array, bool *mask, size_t size); template float findMean(long *array, bool *mask, size_t size); template float findMean(float *array, bool *mask, size_t size); template float findMean(double *array, bool *mask, size_t size); //-------------------------------------------------------------------- template float findStddev(T *array, size_t size) { /// @details Find the rms or standard deviation of an array of /// numbers. Type independent. Calculated by iterating only once, /// using \sum x and \sum x^2 (no call to findMean) /// \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(size_t i=1;i0) stddev = sqrt(double(sumxx)/double(size) - double(sumx*sumx)/double(size*size)); return float(stddev); } template float findStddev(int *array, size_t size); template float findStddev(long *array, size_t size); template float findStddev(float *array, size_t size); template float findStddev(double *array, size_t size); //-------------------------------------------------------------------- template float findStddev(T *array, bool *mask, size_t size) { /// @details Find the rms or standard deviation of an array of /// numbers. Type independent. Calculated by iterating only once, /// using \sum x and \sum x^2 (no call to findMean) /// \param array The array of numbers. /// \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 size The length of the array. /// \return The rms value of the array, returned as a float T sumx=0,sumxx=0; double stddev=0; int ct=0; for(size_t i=0;i0) stddev = sqrt(double(sumxx)/double(ct) - double(sumx*sumx)/double(ct*ct)); return float(stddev); } template float findStddev(int *array, bool *mask, size_t size); template float findStddev(long *array, bool *mask, size_t size); template float findStddev(float *array, bool *mask, size_t size); template float findStddev(double *array, bool *mask, size_t size); //-------------------------------------------------------------------- template T findMedian(T *array, size_t 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(size_t i=0;i(int *array, size_t size, bool changeArray); template long findMedian(long *array, size_t size, bool changeArray); template float findMedian(float *array, size_t size, bool changeArray); template double findMedian(double *array, size_t size, bool changeArray); //-------------------------------------------------------------------- template T findMedian(T *array, bool *mask, size_t size) { /// @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. int goodSize=0,ct=0; for(size_t i=0;i(int *array, bool *mask, size_t size); template long findMedian(long *array, bool *mask, size_t size); template float findMedian(float *array, bool *mask, size_t size); template double findMedian(double *array, bool *mask, size_t size); //-------------------------------------------------------------------- template T findMADFM(T *array, size_t 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(size_t i=0;i(int *array, size_t size, bool changeArray); template long findMADFM(long *array, size_t size, bool changeArray); template float findMADFM(float *array, size_t size, bool changeArray); template double findMADFM(double *array, size_t size, bool changeArray); //-------------------------------------------------------------------- template T findMADFM(T *array, bool *mask, size_t size) { /// @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 median = findMedian(array,mask,size); int goodSize=0,ct=0; for(size_t i=0;i(int *array, bool *mask, size_t size); template long findMADFM(long *array, bool *mask, size_t size); template float findMADFM(float *array, bool *mask, size_t size); template double findMADFM(double *array, bool *mask, size_t size); //-------------------------------------------------------------------- template T findMADFM(T *array, size_t 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(size_t i=0;i(int *array, size_t size, int median, bool changeArray); template long findMADFM(long *array, size_t size, long median, bool changeArray); template float findMADFM(float *array, size_t size, float median, bool changeArray); template double findMADFM(double *array, size_t size, double median, bool changeArray); //-------------------------------------------------------------------- template T findMADFM(T *array, bool *mask, size_t size, T median) { /// @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. int goodSize=0,ct=0; for(size_t i=0;i(int *array, bool *mask, size_t size, int median); template long findMADFM(long *array, bool *mask, size_t size, long median); template float findMADFM(float *array, bool *mask, size_t size, float median); template double findMADFM(double *array, bool *mask, size_t size, double median); //-------------------------------------------------------------------- template void findMedianStats(T *array, size_t 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(size_t i=0;i(int *array, size_t size, int &median, int &madfm); template void findMedianStats(long *array, size_t size, long &median, long &madfm); template void findMedianStats(float *array, size_t size, float &median, float &madfm); template void findMedianStats(double *array, size_t size, double &median, double &madfm); //-------------------------------------------------------------------- template void findMedianStats(T *array, size_t 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(size_t i=0;i(int *array, size_t size, bool *mask, int &median, int &madfm); template void findMedianStats(long *array, size_t size, bool *mask, long &median, long &madfm); template void findMedianStats(float *array, size_t size, bool *mask, float &median, float &madfm); template void findMedianStats(double *array, size_t size, bool *mask, double &median, double &madfm); //-------------------------------------------------------------------- template void findNormalStats(T *array, size_t 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(size_t i=1;i(int *array, size_t size, float &mean, float &stddev); template void findNormalStats(long *array, size_t size, float &mean, float &stddev); template void findNormalStats(float *array, size_t size, float &mean, float &stddev); template void findNormalStats(double *array, size_t size, float &mean, float &stddev); //-------------------------------------------------------------------- template void findNormalStats(T *array, size_t 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(size_t i=0;i(int *array, size_t size, bool *mask, float &mean, float &stddev); template void findNormalStats(long *array, size_t size, bool *mask, float &mean, float &stddev); template void findNormalStats(float *array, size_t size, bool *mask, float &mean, float &stddev); template void findNormalStats(double *array, size_t size, bool *mask, float &mean, float &stddev); //-------------------------------------------------------------------- //-------------------------------------------------------------------- template void findAllStats(T *array, size_t 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(size_t i=0;i(int *array, size_t size, float &mean, float &stddev, int &median, int &madfm); template void findAllStats(long *array, size_t size, float &mean, float &stddev, long &median, long &madfm); template void findAllStats(float *array, size_t size, float &mean, float &stddev, float &median, float &madfm); template void findAllStats(double *array, size_t size, float &mean, float &stddev, double &median, double &madfm); //-------------------------------------------------------------------- template void findAllStats(T *array, size_t 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(size_t i=0;i(int *array, size_t size, bool *mask, float &mean, float &stddev, int &median, int &madfm); template void findAllStats(long *array, size_t size, bool *mask, float &mean, float &stddev, long &median, long &madfm); template void findAllStats(float *array, size_t size, bool *mask, float &mean, float &stddev, float &median, float &madfm); template void findAllStats(double *array, size_t size, bool *mask, float &mean, float &stddev, double &median, double &madfm); //-------------------------------------------------------------------- template void findMedianStatsDiff(T *first, T *second, size_t size, T &median, T &madfm) { /// @details Find the median and the median absolute deviation from /// the median value of the difference between two arrays of /// numbers. Type independent. The difference is defined as first - /// second. /// /// \param first The first array /// \param second The second array /// \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(size_t i=0;i(int *first, int *second, size_t size, int &median, int &madfm); template void findMedianStatsDiff(long *first, long *second, size_t size, long &median, long &madfm); template void findMedianStatsDiff(float *first, float *second, size_t size, float &median, float &madfm); template void findMedianStatsDiff(double *first, double *second, size_t size, double &median, double &madfm); //-------------------------------------------------------------------- template void findMedianStatsDiff(T *first, T *second, size_t size, bool *mask, T &median, T &madfm) { /// @details Find the median and the median absolute deviation from /// the median value of the difference between two arrays of /// numbers, where some elements are masked out. The mask is defined /// by an array of bool variables. Type independent. The difference /// is defined as first - second. /// /// \param first The first array /// \param second The second array /// \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(size_t i=0;i(int *first, int *second, size_t size, bool *mask, int &median, int &madfm); template void findMedianStatsDiff(long *first, long *second, size_t size, bool *mask, long &median, long &madfm); template void findMedianStatsDiff(float *first, float *second, size_t size, bool *mask, float &median, float &madfm); template void findMedianStatsDiff(double *first, double *second, size_t size, bool *mask, double &median, double &madfm); //-------------------------------------------------------------------- template void findNormalStatsDiff(T *first, T *second, size_t size, float &mean, float &stddev) { /// @details /// Find the mean and rms or standard deviation of the difference between two arrays of /// numbers. The difference is defined as first - second. Type independent. /// /// \param first The first array /// \param second The second array /// \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 = first[0]-second[0]; for(size_t i=1;i(int *first, int *second, size_t size, float &mean, float &stddev); template void findNormalStatsDiff(long *first, long *second, size_t size, float &mean, float &stddev); template void findNormalStatsDiff(float *first, float *second, size_t size, float &mean, float &stddev); template void findNormalStatsDiff(double *first, double *second, size_t size, float &mean, float &stddev); //-------------------------------------------------------------------- template void findNormalStatsDiff(T *first, T *second, size_t size, bool *mask, float &mean, float &stddev) { /// @details Find the mean and rms or standard deviation of the /// difference between two arrays of numbers, where some elements /// are masked out. The mask is defined by an array of bool /// variables, and the difference is defined as first - second. Type /// independent. /// /// \param first The first array /// \param second The second array /// \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(size_t i=0;i(int *first, int *second, size_t size, bool *mask, float &mean, float &stddev); template void findNormalStatsDiff(long *first, long *second, size_t size, bool *mask, float &mean, float &stddev); template void findNormalStatsDiff(float *first, float *second, size_t size, bool *mask, float &mean, float &stddev); template void findNormalStatsDiff(double *first, double *second, size_t size, bool *mask, float &mean, float &stddev); //--------------------------------------------------------------------