1 #ifndef _theplu_yat_statistics_percentiler_
2 #define _theplu_yat_statistics_percentiler_
26 #include "yat/utility/concept_check.h"
27 #include "yat/utility/DataWeight.h"
28 #include "yat/utility/iterator_traits.h"
29 #include "yat/utility/yat_assert.h"
30 #include "yat/utility/WeightIterator.h"
32 #include <boost/concept_check.hpp>
43 namespace statistics {
96 template<
typename RandomAccessIterator>
98 RandomAccessIterator last)
const
100 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<RandomAccessIterator>));
103 return std::numeric_limits<double>::quiet_NaN();
104 return calculate(first, last, sorted_,
112 template<
typename RandomAccessIterator>
113 double calculate(RandomAccessIterator first, RandomAccessIterator last,
117 template<
typename RandomAccessIterator>
118 double calculate(RandomAccessIterator first, RandomAccessIterator last,
131 template<
typename RandomAccessIterator>
133 Percentiler::calculate(RandomAccessIterator first,
134 RandomAccessIterator last,
142 size_t n = last - first;
148 double j = n * perc_ / 100.0;
149 size_t i =
static_cast<size_t>(j);
151 return (first[i]+first[i-1])/2;
155 std::vector<double> v_copy;
156 v_copy.reserve(std::distance(first,last));
157 std::copy(first, last, std::back_inserter(v_copy));
158 std::sort(v_copy.begin(), v_copy.end());
159 return calculate(v_copy.begin(), v_copy.end(),
true, tag);
164 template<
typename RandomAccessIterator>
165 double Percentiler::calculate(RandomAccessIterator first,
166 RandomAccessIterator last,
168 utility::weighted_iterator_tag tag)
const
171 utility::iterator_traits<RandomAccessIterator> trait;
172 std::vector<double> accum_w;
173 accum_w.reserve(last-first);
174 std::partial_sum(weight_iterator(first),
175 weight_iterator(last),
176 std::back_inserter(accum_w));
178 double w_bound=perc_/100.0*accum_w.back();
179 std::vector<double>::const_iterator upper(accum_w.begin());
181 while (upper!=accum_w.end() && *upper <= w_bound+margin)
183 while (upper!=accum_w.begin() &&
184 (upper==accum_w.end() ||
185 trait.weight(first+(upper-accum_w.begin()))==0.0))
187 std::vector<double>::const_iterator lower(upper);
188 while ( *(lower-1)>=w_bound-margin && lower>accum_w.begin())
191 return (trait.data(first+(upper-accum_w.begin()))+
192 trait.data(first+(lower-accum_w.begin())))/2;
195 std::vector<utility::DataWeight> v_copy;
196 v_copy.reserve(last-first);
197 std::copy(first, last, std::back_inserter(v_copy));
198 std::sort(v_copy.begin(), v_copy.end());
199 return calculate(v_copy.begin(), v_copy.end(),
true, tag);