Commit 50ffc781 by Fred Tingaud Committed by Dominic Hamon

Optimize by using nth_element instead of partial_sort to find the median. (#565)

parent 2844167f
...@@ -36,16 +36,19 @@ double StatisticsMean(const std::vector<double>& v) { ...@@ -36,16 +36,19 @@ double StatisticsMean(const std::vector<double>& v) {
double StatisticsMedian(const std::vector<double>& v) { double StatisticsMedian(const std::vector<double>& v) {
if (v.size() < 3) return StatisticsMean(v); if (v.size() < 3) return StatisticsMean(v);
std::vector<double> partial; std::vector<double> copy(v);
// we need roundDown(count/2)+1 slots
partial.resize(1 + (v.size() / 2)); auto center = copy.begin() + v.size() / 2;
std::partial_sort_copy(v.begin(), v.end(), partial.begin(), partial.end()); std::nth_element(copy.begin(), center, copy.end());
// did we have odd number of samples?
// if yes, then the last element of partially-sorted vector is the median // did we have an odd number of samples?
// it no, then the average of the last two elements is the median // if yes, then center is the median
// it no, then we are looking for the average between center and the value before
if(v.size() % 2 == 1) if(v.size() % 2 == 1)
return partial.back(); return *center;
return (partial[partial.size() - 2] + partial[partial.size() - 1]) / 2.0; auto center2 = copy.begin() + v.size() / 2 - 1;
std::nth_element(copy.begin(), center2, copy.end());
return (*center + *center2) / 2.0;
} }
// Return the sum of the squares of this sample set // Return the sum of the squares of this sample set
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment