00001 #ifndef _cmEstimator_H
00002 #define _cmEstimator_H
00003
00010 #include <numeric>
00011 #include <algorithm>
00012 #include <functional>
00013 #include "General.h"
00014 #include <iostream>
00015 #include <vector>
00016
00017 template <typename TYPE>
00018 class cmEstimator{
00019
00020 public:
00021
00022 typedef typename std::vector<TYPE> contType;
00023 typedef typename contType::iterator iter_type;
00024
00029 cmEstimator(TYPE outlier = TYPE(3),
00030 unsigned int iter = 1u):
00031 m_outlier(outlier),
00032 m_iter(iter){}
00033
00035 virtual ~cmEstimator() {}
00036
00038 TYPE outlierCut() const {return m_outlier;}
00039
00044 contType calculate(contType& input);
00045
00047 int reject() const {return m_reject;}
00048
00049 private:
00050
00052 void initMask(unsigned int contSize);
00053
00055 TYPE mean(contType& input) const;
00056
00058 TYPE variance(contType& input) const;
00059
00061 void subtractMean(contType& input, TYPE mean) const;
00062
00064 void cmSubtraction(contType& input, TYPE slope) const;
00065
00067 TYPE slope(contType& input) const;
00068
00070 void setToZero(contType& input, TYPE s);
00071
00072 TYPE m_outlier;
00073 std::vector<unsigned int> m_mask;
00074 unsigned int m_iter;
00075 int m_reject;
00076
00077 };
00078
00079 template <typename TYPE>
00080 inline typename std::vector<TYPE> cmEstimator<TYPE>::calculate(contType& inputData){
00081
00082
00083 m_reject = 0;
00084 initMask(inputData.size());
00085
00086
00087 TYPE mean1 = mean(inputData);
00088
00089
00090 contType firstPass;
00091 firstPass.insert(firstPass.begin(), inputData.begin(),inputData.end());
00092 subtractMean(firstPass,mean1);
00093
00094
00095 TYPE s1 = slope(firstPass);
00096
00097
00098 cmSubtraction(firstPass,s1);
00099
00100 for (unsigned int it = 0u ; it < m_iter; ++it){
00101
00102 contType tPass;
00103 tPass.insert(tPass.begin(), firstPass.begin(), firstPass.end());
00104
00105
00106 setToZero(tPass, variance(tPass));
00107
00108
00109 TYPE mean2 = mean(tPass);
00110 subtractMean(tPass,mean2);
00111 TYPE s2 = slope(tPass);
00112
00113 subtractMean(firstPass,mean2);
00114 cmSubtraction(firstPass,s2);
00115 }
00116
00117 return firstPass;
00118 }
00119
00120 template <typename TYPE>
00121 void cmEstimator<TYPE>::initMask(unsigned int contSize) {
00122
00123 m_mask.clear();
00124 for (unsigned int i = 0; i< contSize; ++i){
00125 m_mask.push_back(0u);
00126 }
00127 }
00128
00129 template <typename TYPE>
00130 inline TYPE cmEstimator<TYPE>::mean(contType& input) const{
00131
00132 TYPE sum = TYPE(0);
00133 for (unsigned int i = 0; i< input.size(); ++i){
00134 if (m_mask[i] == 0) sum += input[i];
00135 }
00136 return sum/TYPE(input.size()-m_reject);
00137 }
00138
00139 template <typename TYPE>
00140 inline TYPE cmEstimator<TYPE>::variance(contType& input) const{
00141 TYPE sum2 = TYPE(0);
00142 for (unsigned int i = 0; i< input.size(); ++i){
00143 if (m_mask[i] == 0) sum2 += pow(input[i],2.);
00144 }
00145 return sum2/TYPE(input.size()-m_reject);
00146 }
00147
00148 template <typename TYPE>
00149 void cmEstimator<TYPE>::subtractMean(contType& input, TYPE mean) const{
00150
00151 for (unsigned int i = 0; i< input.size(); ++i){
00152 if (m_mask[i] == 0){
00153 input[i] = input[i] - mean;
00154 }
00155 }
00156 }
00157
00158 template <typename TYPE>
00159 inline TYPE cmEstimator<TYPE>::slope(contType& input) const{
00160
00161
00162 TYPE s = TYPE(0);
00163 for (unsigned int i =0; i< input.size(); ++i){
00164 if (m_mask[i] == 0) s += (input[i] *(int(i)-16));
00165 }
00166
00167
00168 return s/(TYPE(2736));
00169
00170 }
00171
00172 template <typename TYPE>
00173 inline void cmEstimator<TYPE>::cmSubtraction(contType& input, TYPE s) const{
00174
00175
00176 for ( unsigned int i = 0; i< input.size(); ++i){
00177 input[i] = input[i] - (s*(int(i)-16));
00178 }
00179 }
00180
00181 template <typename TYPE>
00182 inline void cmEstimator<TYPE>::setToZero(contType& input, TYPE var){
00183
00184
00185 for ( unsigned int i = 0; i< input.size(); ++i){
00186 if ((m_mask[i] == 0)&&(pow(input[i],2.0)> var/m_outlier)){
00187
00188 m_mask[i] = 1u;
00189 if (i> 0) m_mask[i-1] = 1u;
00190 if (i< input.size()-1) m_mask[i+1] = 1u;
00191 ++m_reject;
00192 }
00193 }
00194 }
00195
00196 #endif // _cmEstimator_H