yat  0.17.3pre
TukeyBiweightEstimator.h
1 #ifndef _theplu_yat_statistics_tukey_biweight_estimator
2 #define _theplu_yat_statistics_tukey_biweight_estimator
3 
4 // $Id: TukeyBiweightEstimator.h 3873 2020-03-05 00:08:33Z 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:
76  explicit TukeyBiweightEstimator(double cutoff=4.685, bool sorted=false)
77  : cutoff_(cutoff), sorted_(sorted) {}
78 
89  template<typename RandomAccessIterator>
90  double operator()(RandomAccessIterator first,
91  RandomAccessIterator last) const;
92 
93  private:
94  double cutoff_;
95  bool sorted_;
96 
97  template<typename RandomAccessIterator>
98  double estimate(RandomAccessIterator first,
99  RandomAccessIterator last) const;
100 
101  template<typename InputIterator>
102  double estimate(InputIterator first, InputIterator last,
103  double center, double spread) const;
104  };
105 
106  template<typename RandomAccessIterator>
107  double TukeyBiweightEstimator::operator()(RandomAccessIterator first,
108  RandomAccessIterator last) const
109  {
110  using boost_concepts::RandomAccessTraversal;
111  BOOST_CONCEPT_ASSERT((RandomAccessTraversal<RandomAccessIterator>));
113  BOOST_CONCEPT_ASSERT((DataIteratorConcept<RandomAccessIterator>));
114 
115  if (sorted_)
116  return estimate(first, last);
117 
118  // if not sorted, create a sorted copy
119  typedef typename std::iterator_traits<RandomAccessIterator> traits;
120  std::vector<typename traits::value_type> vec(first, last);
121  std::sort(vec.begin(), vec.end());
122  return estimate(vec.begin(), vec.end());
123  }
124 
125 
126  template<typename RandomAccessIterator>
127  double TukeyBiweightEstimator::estimate(RandomAccessIterator first,
128  RandomAccessIterator last) const
129  {
130  const double scale = mad(first, last, true);
131  double m = median(first, last, true);
132  // if mad is zero all (non-zero weight) data points are equal and
133  // median is the only sensible estimate. Also, calculations below
134  // would "divide by zero" so we need to interupt here.
135  if (scale==0)
136  return m;
137  double m0 = m+1.0;
138  size_t epoch = 0;
139  // FIXME: let user define convergence requirement
140  while (m!=m0) {
141  m0 = m;
142  m = estimate(first, last, m, scale);
143  ++epoch;
144  // FIXME: let user define maximal epochs
145  if (epoch>1000)
146  utility::runtime_error("TukeyBiweightIterator: too many epochs");
147  }
148  return m;
149  }
150 
151 
152  template<typename InputIterator>
153  double TukeyBiweightEstimator::estimate(InputIterator first,
154  InputIterator last,
155  double center, double spread) const
156  {
157  double scale = spread*cutoff_;
159  regression::TukeyBiweight biweight;
161  for ( ; first!=last; ++first) {
162  double x = traits.data(first);
163  double w = traits.weight(first) * biweight((x-center)/scale);
164  averager.add(x, w);
165  }
166  return averager.mean();
167  }
168 
169 }}} // end of namespace theplu yat statistics
170 # endif
TukeyBiweightEstimator(double cutoff=4.685, bool sorted=false)
Constructor.
Definition: TukeyBiweightEstimator.h:76
double mad(RandomAccessIterator first, RandomAccessIterator last, bool sorted=false)
Median absolute deviation from median.
Definition: utility.h:406
data_reference data(Iter iter) const
Definition: iterator_traits.h:440
double operator()(RandomAccessIterator first, RandomAccessIterator last) const
Definition: TukeyBiweightEstimator.h:107
Concept check for Data Iterator.
Definition: concept_check.h:240
Definition: iterator_traits.h:412
double mean(void) const
Calculate the weighted mean.
The Department of Theoretical Physics namespace as we define it.
Class to calulate averages with weights.
Definition: AveragerWeighted.h:66
void add(const double d, const double w=1)
double median(RandomAccessIterator first, RandomAccessIterator last, bool sorted=false)
Definition: utility.h:429
Class used for all runtime error detected within yat library.
Definition: Exception.h:38
Tukey&#39;s Biweight Estimator.
Definition: TukeyBiweightEstimator.h:64
Definition: TukeyBiweight.h:34
weight_reference weight(Iter iter) const
Definition: iterator_traits.h:446
Definition: averager_traits.h:79

Generated on Thu Aug 27 2020 03:33:18 for yat by  doxygen 1.8.11