@@ -36,16 +36,19 @@ double StatisticsMean(const std::vector<double>& v) {
3636
3737double StatisticsMedian (const std::vector<double >& v) {
3838 if (v.size () < 3 ) return StatisticsMean (v);
39- std::vector<double > partial;
40- // we need roundDown(count/2)+1 slots
41- partial.resize (1 + (v.size () / 2 ));
42- std::partial_sort_copy (v.begin (), v.end (), partial.begin (), partial.end ());
43- // did we have odd number of samples?
44- // if yes, then the last element of partially-sorted vector is the median
45- // it no, then the average of the last two elements is the median
39+ std::vector<double > copy (v);
40+
41+ auto center = copy.begin () + v.size () / 2 ;
42+ std::nth_element (copy.begin (), center, copy.end ());
43+
44+ // did we have an odd number of samples?
45+ // if yes, then center is the median
46+ // it no, then we are looking for the average between center and the value before
4647 if (v.size () % 2 == 1 )
47- return partial.back ();
48- return (partial[partial.size () - 2 ] + partial[partial.size () - 1 ]) / 2.0 ;
48+ return *center;
49+ auto center2 = copy.begin () + v.size () / 2 - 1 ;
50+ std::nth_element (copy.begin (), center2, copy.end ());
51+ return (*center + *center2) / 2.0 ;
4952}
5053
5154// Return the sum of the squares of this sample set
0 commit comments