// ----------------------------------------------------------------------- // 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 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 findMedianDiff(T *first, T *second, 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. T *newarray = new T[size]; for(size_t i=0;i(int *first, int *second, size_t size); template long findMedianDiff(long *first, long *second, size_t size); template float findMedianDiff(float *first, float *second, size_t size); template double findMedianDiff(double *first, double *second, size_t size); //-------------------------------------------------------------------- template T findMedian(T *array, std::vector mask, size_t size) { /// @details /// Find the median value of an array of numbers. Type independent. This will create a new array that gets partially sorted. /// \param array The array of numbers. /// \param mask Whether a given array value should be included in calculations. NB: mask=true implies use this array value. /// \param size The length of the array. /// \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, std::vector mask, size_t size); template long findMedian(long *array, std::vector mask, size_t size); template float findMedian(float *array, std::vector mask, size_t size); template double findMedian(double *array, std::vector mask, size_t size); //-------------------------------------------------------------------- template T findMedianDiff(T *first, T *second, std::vector 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 *first, int *second, std::vector mask, size_t size); template long findMedianDiff(long *first, long *second, std::vector mask, size_t size); template float findMedianDiff(float *first, float *second, std::vector mask, size_t size); template double findMedianDiff(double *first, double *second, std::vector 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 findMADFMDiff(T *first, T *second, 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 *newarray = new T[size]; T median = findMedianDiff(first,second,size); T madfm; bool isEven = ((size%2)==0); for(size_t i=0;i(int *first, int *second, size_t size); template long findMADFMDiff(long *first, long *second, size_t size); template float findMADFMDiff(float *first, float *second, size_t size); template double findMADFMDiff(double *first, double *second, size_t size); //-------------------------------------------------------------------- template T findMADFM(T *array, std::vector 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, std::vector mask, size_t size); template long findMADFM(long *array, std::vector mask, size_t size); template float findMADFM(float *array, std::vector mask, size_t size); template double findMADFM(double *array, std::vector mask, size_t size); //-------------------------------------------------------------------- template T findMADFMDiff(T *first, T *second, std::vector 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 = findMedianDiff(first,second,mask,size); int goodSize=0,ct=0; for(size_t i=0;i(int *first, int *second, std::vector mask, size_t size); template long findMADFMDiff(long *first, long *second, std::vector mask, size_t size); template float findMADFMDiff(float *first, float *second, std::vector mask, size_t size); template double findMADFMDiff(double *first, double *second, std::vector 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 findMADFMDiff(T *first, T *second, 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. T *newarray = new T[size]; T madfm; bool isEven = ((size%2)==0); for(size_t i=0;i(int *first, int *second, size_t size, int median); template long findMADFMDiff(long *first, long *second, size_t size, long median); template float findMADFMDiff(float *first, float *second, size_t size, float median); template double findMADFMDiff(double *first, double *second, size_t size, double median); //-------------------------------------------------------------------- template T findMADFM(T *array, std::vector 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, std::vector mask, size_t size, int median); template long findMADFM(long *array, std::vector mask, size_t size, long median); template float findMADFM(float *array, std::vector mask, size_t size, float median); template double findMADFM(double *array, std::vector mask, size_t size, double median); //-------------------------------------------------------------------- template T findMADFMDiff(T *first, T *second, std::vector 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 *first, int *second, std::vector mask, size_t size, int median); template long findMADFMDiff(long *first, long *second, std::vector mask, size_t size, long median); template float findMADFMDiff(float *first, float *second, std::vector mask, size_t size, float median); template double findMADFMDiff(double *first, double *second, std::vector 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(newarray,size,true); // madfm = findMADFM(newarray,size,true); madfm = findMADFM(newarray,size,median,true); delete [] newarray; } template void findMedianStats(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, std::vector 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(newarray,goodSize,true); // madfm = findMADFM(newarray,goodSize,true); madfm = findMADFM(newarray,goodSize,median,true); delete [] newarray; } template void findMedianStats(int *array, size_t size, std::vector mask, int &median, int &madfm); template void findMedianStats(long *array, size_t size, std::vector mask, long &median, long &madfm); template void findMedianStats(float *array, size_t size, std::vector mask, float &median, float &madfm); template void findMedianStats(double *array, size_t size, std::vector mask, 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(newarray,size,true); // madfm = findMADFM(newarray,size,true); madfm = findMADFM(newarray,size,median,true); delete [] newarray; } template void findMedianStatsDiff(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, std::vector 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(newarray,goodSize,true); // madfm = findMADFM(newarray,goodSize,true); madfm = findMADFM(newarray,goodSize,median,true); delete [] newarray; } template void findMedianStatsDiff(int *first, int *second, size_t size, std::vector mask, int &median, int &madfm); template void findMedianStatsDiff(long *first, long *second, size_t size, std::vector mask, long &median, long &madfm); template void findMedianStatsDiff(float *first, float *second, size_t size, std::vector mask, float &median, float &madfm); template void findMedianStatsDiff(double *first, double *second, size_t size, std::vector mask, double &median, double &madfm); //--------------------------------------------------------------------