xref: /openbmc/phosphor-fan-presence/control/utility.cpp (revision 3e1bb274a9871c2f78488a84c748654394d28fbd)
1*3e1bb274SMatthew Barth #include "utility.hpp"
2*3e1bb274SMatthew Barth 
3014f07c7SMatthew Barth #include <algorithm>
4014f07c7SMatthew Barth #include <stdexcept>
5014f07c7SMatthew Barth 
6014f07c7SMatthew Barth namespace phosphor
7014f07c7SMatthew Barth {
8014f07c7SMatthew Barth namespace fan
9014f07c7SMatthew Barth {
10014f07c7SMatthew Barth namespace control
11014f07c7SMatthew Barth {
12014f07c7SMatthew Barth namespace utility
13014f07c7SMatthew Barth {
14014f07c7SMatthew Barth 
getMedian(std::vector<int64_t> & values)15014f07c7SMatthew Barth int64_t getMedian(std::vector<int64_t>& values)
16014f07c7SMatthew Barth {
17014f07c7SMatthew Barth     if (values.empty())
18014f07c7SMatthew Barth     {
19014f07c7SMatthew Barth         throw std::out_of_range("getMedian(): Empty list of values");
20014f07c7SMatthew Barth     }
21014f07c7SMatthew Barth     const auto oddIt = values.begin() + values.size() / 2;
22014f07c7SMatthew Barth     std::nth_element(values.begin(), oddIt, values.end());
23014f07c7SMatthew Barth     auto median = *oddIt;
24014f07c7SMatthew Barth     // Determine median for even number of values
25014f07c7SMatthew Barth     if (values.size() % 2 == 0)
26014f07c7SMatthew Barth     {
27014f07c7SMatthew Barth         // Use average of middle 2 values for median
28014f07c7SMatthew Barth         const auto evenIt = values.begin() + values.size() / 2 - 1;
29014f07c7SMatthew Barth         std::nth_element(values.begin(), evenIt, values.end());
30014f07c7SMatthew Barth         median = (median + *evenIt) / 2;
31014f07c7SMatthew Barth     }
32014f07c7SMatthew Barth 
33014f07c7SMatthew Barth     return median;
34014f07c7SMatthew Barth }
35014f07c7SMatthew Barth 
36014f07c7SMatthew Barth } // namespace utility
37014f07c7SMatthew Barth } // namespace control
38014f07c7SMatthew Barth } // namespace fan
39014f07c7SMatthew Barth } // namespace phosphor
40