yat  0.21pre
TukeyBiweightEstimator.h
1 #ifndef _theplu_yat_statistics_tukey_biweight_estimator
2 #define _theplu_yat_statistics_tukey_biweight_estimator
3 
4 // $Id: TukeyBiweightEstimator.h 3925 2020-07-05 23:00:55Z peter $
5 
6 /*
7  Copyright (C) 2011, 2012, 2014, 2016, 2020 Peter Johansson
8 
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10 
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15 
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <http://www.gnu.org/licenses/>.
23 */
24 
25 #include "AveragerWeighted.h"
26 #include "utility.h"
27 
28 #include "yat/regression/TukeyBiweight.h"
29 
30 #include "yat/utility/concept_check.h"
31 #include "yat/utility/Exception.h"
32 #include "yat/utility/iterator_traits.h"
33 
34 #include <boost/concept_check.hpp>
35 #include <boost/iterator/iterator_concepts.hpp>
36 
37 #include <algorithm>
38 #include <iterator>
39 #include <limits>
40 #include <vector>
41 
42 namespace theplu {
43 namespace yat {
44 namespace statistics {
45 
65  {
66  public:
70  class Stopper
71  {
72  public:
76  Stopper(size_t max_epochs=1000);
80  virtual bool operator()(double current, double previous) const=0;
81  protected:
83  size_t epochs(void) const;
85  size_t max_epochs(void) const;
86  private:
87  size_t epochs_;
88  size_t max_epochs_;
89  friend class TukeyBiweightEstimator;
90  bool stop(double current, double previous);
91  };
92 
102  explicit TukeyBiweightEstimator(double cutoff=4.685, bool sorted=false)
103  : cutoff_(cutoff), sorted_(sorted) {}
104 
115  template<typename RandomAccessIterator>
116  double operator()(RandomAccessIterator first,
117  RandomAccessIterator last) const;
118 
122  template<typename RandomAccessIterator>
123  double operator()(RandomAccessIterator first,
124  RandomAccessIterator last,
125  Stopper& stopper) const;
126 
127  private:
128  double cutoff_;
129  bool sorted_;
130 
131  template<typename RandomAccessIterator>
132  double estimate(RandomAccessIterator first,
133  RandomAccessIterator last,
134  Stopper& stopper) const;
135 
136  template<typename InputIterator>
137  double estimate(InputIterator first, InputIterator last,
138  double center, double spread) const;
139 
140  class DefaultStopper : public Stopper
141  {
142  public:
143  bool operator()(double current, double previous) const;
144  };
145  };
146 
147 
148  template<typename RandomAccessIterator>
149  double TukeyBiweightEstimator::operator()(RandomAccessIterator first,
150  RandomAccessIterator last) const
151  {
152  TukeyBiweightEstimator::DefaultStopper stopper;
153  return (*this)(first, last, stopper);
154  }
155 
156 
157  template<typename RandomAccessIterator>
158  double
159  TukeyBiweightEstimator::operator()(RandomAccessIterator first,
160  RandomAccessIterator last,
161  TukeyBiweightEstimator::Stopper& stopper) const
162  {
163  using boost_concepts::RandomAccessTraversal;
164  BOOST_CONCEPT_ASSERT((RandomAccessTraversal<RandomAccessIterator>));
166  BOOST_CONCEPT_ASSERT((DataIteratorConcept<RandomAccessIterator>));
167 
168  if (sorted_)
169  return estimate(first, last, stopper);
170 
171  // if not sorted, create a sorted copy
172  typedef typename std::iterator_traits<RandomAccessIterator> traits;
173  std::vector<typename traits::value_type> vec(first, last);
174  std::sort(vec.begin(), vec.end());
175  return estimate(vec.begin(), vec.end(), stopper);
176  }
177 
178 
179  template<typename RandomAccessIterator>
180  double
181  TukeyBiweightEstimator::estimate(RandomAccessIterator first,
182  RandomAccessIterator last,
183  TukeyBiweightEstimator::Stopper& stopper) const
184  {
185  const double scale = mad(first, last, true);
186  double m = median(first, last, true);
187  // if mad is zero all (non-zero weight) data points are equal and
188  // median is the only sensible estimate. Also, calculations below
189  // would "divide by zero" so we need to interupt here.
190  if (scale==0)
191  return m;
192  double m0 = m+1.0;
193  while (!stopper.stop(m, m0)) {
194  m0 = m;
195  m = estimate(first, last, m, scale);
196  }
197  return m;
198  }
199 
200 
201  template<typename InputIterator>
202  double TukeyBiweightEstimator::estimate(InputIterator first,
203  InputIterator last,
204  double center, double spread) const
205  {
206  double scale = spread*cutoff_;
207  AveragerWeighted averager;
208  regression::TukeyBiweight biweight;
209  utility::iterator_traits<InputIterator> traits;
210  for ( ; first!=last; ++first) {
211  double x = traits.data(first);
212  double w = traits.weight(first) * biweight((x-center)/scale);
213  averager.add(x, w);
214  }
215  return averager.mean();
216  }
217 
218 }}} // end of namespace theplu yat statistics
219 # endif
TukeyBiweightEstimator(double cutoff=4.685, bool sorted=false)
Constructor.
Definition: TukeyBiweightEstimator.h:102
double mad(RandomAccessIterator first, RandomAccessIterator last, bool sorted=false)
Median absolute deviation from median.
Definition: utility.h:406
Concept check for Data Iterator.
Definition: concept_check.h:240
The Department of Theoretical Physics namespace as we define it.
virtual bool operator()(double current, double previous) const =0
double median(RandomAccessIterator first, RandomAccessIterator last, bool sorted=false)
Definition: utility.h:429
Tukey&#39;s Biweight Estimator.
Definition: TukeyBiweightEstimator.h:64
Definition: TukeyBiweightEstimator.h:70
double operator()(RandomAccessIterator first, RandomAccessIterator last) const
Definition: TukeyBiweightEstimator.h:149

Generated on Wed Jan 25 2023 03:34:29 for yat by  doxygen 1.8.14