00001 #ifndef _ModeFunctions_H
00002 #define _ModeFunctions_H 1
00003
00004 #include <algorithm>
00005 #include <numeric>
00006 #include <vector>
00007 #include <utility>
00008
00009
00018 namespace ModeFunctions{
00019
00026 template <typename TYPE>
00027 double shorth(TYPE start, TYPE stop);
00028
00035 template <typename TYPE>
00036 double LMS(TYPE start, TYPE stop);
00037
00045 template <typename TYPE>
00046 std::pair<TYPE,TYPE> halfSample(TYPE start, TYPE stop);
00047
00054 template <typename TYPE>
00055 double halfSampleWidth(TYPE start, TYPE stop);
00056
00063 template <typename TYPE>
00064 double generalizedMean(TYPE start, TYPE stop, double p = -0.5);
00065 }
00066
00067 template <typename TYPE>
00068 inline std::pair<TYPE,TYPE> ModeFunctions::halfSample(TYPE start, TYPE stop){
00069 const unsigned int halfSize = (unsigned int)((stop-start)/2u);
00070 unsigned int pos = 0u;
00071 unsigned int bestpos = halfSize-1u;
00072 for (TYPE iter = start; iter != stop ; ++iter, ++pos){
00073 if (pos < halfSize){
00074 if (*(iter+halfSize) - *iter < *(start+bestpos+halfSize) - *(start+bestpos) ) {
00075 bestpos = pos;
00076 }
00077 }
00078 }
00079 return std::make_pair(start+bestpos, start+bestpos+halfSize);
00080 }
00081
00082 template <typename TYPE>
00083 inline double ModeFunctions::halfSampleWidth(TYPE start, TYPE stop){
00084
00085 if (start == stop){
00086 return 0.0;
00087 }
00088 else if (stop - start <= 2) {
00089 return 0.5* fabs(*start - *stop);
00090 }
00091 std::pair<TYPE,TYPE> bestpos = halfSample(start,stop);
00092 return fabs(*bestpos.first - *bestpos.second);
00093 }
00094
00095 template<typename TYPE>
00096 inline double ModeFunctions::shorth(TYPE start, TYPE stop){
00097
00098 if (start == stop) {
00099 return 0.0;
00100 }
00101 else if (stop - start == 1) {
00102 return *start;
00103 }
00104 else if (stop - start == 2){
00105 return (*start + *(start+1))/2u;
00106 }
00107 std::pair<TYPE,TYPE> bestpos = halfSample(start,stop);
00108 const unsigned int halfSize = (unsigned int)((stop-start)/2u);
00109 return std::accumulate(bestpos.first, bestpos.second,0.0)/double(halfSize);
00110 }
00111
00112 template <typename TYPE>
00113 inline double ModeFunctions::LMS(TYPE start, TYPE stop){
00114
00115 if (start == stop) {
00116 return 0.0;
00117 }
00118 else if (stop - start == 1) {
00119 return *start;
00120 }
00121 else if (stop - start == 2){
00122 return 0.5*(*start + *(start+1));
00123 }
00124
00125 std::pair<TYPE,TYPE> bestPos = halfSample(start,stop);
00126 return 0.5* (*(bestPos.first) + *(bestPos.second));
00127 }
00128
00129 template <typename TYPE>
00130 inline double ModeFunctions::generalizedMean(TYPE start, TYPE stop, double power){
00131
00132 double sum = 0.0; unsigned int size = 0u;
00133 for (TYPE iter = start; iter != stop; ++iter, ++size){
00134 if (power > 0.0){
00135 sum += pow(*iter,power);
00136 }
00137 else {
00138
00139 double value = std::max(1e-5,fabs(*iter));
00140 sum +=pow(value,power);
00141 }
00142 }
00143 return size != 0u ? pow(sum/double(size),1.0/power) : 0.0;
00144 }
00145
00146
00147 #endif