Given a vector of values (sorted or not), calculate the median.
| 35 | |
| 36 | // Given a vector of values (sorted or not), calculate the median. |
| 37 | static double Median(std::vector<double> &&values) { |
| 38 | const size_t n = values.size(); |
| 39 | if (n == 0) return 0; |
| 40 | const auto middle = values.begin() + (n / 2); |
| 41 | // Put the middle value in its place. |
| 42 | std::nth_element(values.begin(), middle, values.end()); |
| 43 | if (n & 1) { |
| 44 | return *middle; |
| 45 | } |
| 46 | // Return the average of the two elements, the max_element lower than |
| 47 | // *middle is found between begin and middle as a post-cond of |
| 48 | // nth_element. |
| 49 | const auto lower_middle = std::max_element(values.begin(), middle); |
| 50 | // Preventing overflow. We know that '*lower_middle <= *middle'. |
| 51 | // If both are on opposite sides of zero, the sum won't overflow, otherwise |
| 52 | // the difference won't overflow. |
| 53 | if (*lower_middle <= 0 && *middle >= 0) { |
| 54 | return (*lower_middle + *middle) / 2; |
| 55 | } |
| 56 | return *lower_middle + (*middle - *lower_middle) / 2; |
| 57 | } |
| 58 | |
| 59 | // Given a set of values, calculates the scaled Median Absolute Deviation (a |
| 60 | // robust approximation to the standard deviation). This is calculated as the |
no test coverage detected