xref: /openbmc/phosphor-fan-presence/control/utility.cpp (revision 014f07c7b5644b1c48146e2cb76fb5a8ce69839e)
1*014f07c7SMatthew Barth #include <algorithm>
2*014f07c7SMatthew Barth #include <stdexcept>
3*014f07c7SMatthew Barth 
4*014f07c7SMatthew Barth #include "utility.hpp"
5*014f07c7SMatthew Barth 
6*014f07c7SMatthew Barth namespace phosphor
7*014f07c7SMatthew Barth {
8*014f07c7SMatthew Barth namespace fan
9*014f07c7SMatthew Barth {
10*014f07c7SMatthew Barth namespace control
11*014f07c7SMatthew Barth {
12*014f07c7SMatthew Barth namespace utility
13*014f07c7SMatthew Barth {
14*014f07c7SMatthew Barth 
15*014f07c7SMatthew Barth int64_t getMedian(std::vector<int64_t>& values)
16*014f07c7SMatthew Barth {
17*014f07c7SMatthew Barth     if (values.empty())
18*014f07c7SMatthew Barth     {
19*014f07c7SMatthew Barth         throw std::out_of_range("getMedian(): Empty list of values");
20*014f07c7SMatthew Barth     }
21*014f07c7SMatthew Barth     const auto oddIt = values.begin() + values.size() / 2;
22*014f07c7SMatthew Barth     std::nth_element(values.begin(), oddIt, values.end());
23*014f07c7SMatthew Barth     auto median = *oddIt;
24*014f07c7SMatthew Barth     // Determine median for even number of values
25*014f07c7SMatthew Barth     if (values.size() % 2 == 0)
26*014f07c7SMatthew Barth     {
27*014f07c7SMatthew Barth         // Use average of middle 2 values for median
28*014f07c7SMatthew Barth         const auto evenIt = values.begin() + values.size() / 2 - 1;
29*014f07c7SMatthew Barth         std::nth_element(values.begin(), evenIt, values.end());
30*014f07c7SMatthew Barth         median = (median + *evenIt) / 2;
31*014f07c7SMatthew Barth     }
32*014f07c7SMatthew Barth 
33*014f07c7SMatthew Barth     return median;
34*014f07c7SMatthew Barth }
35*014f07c7SMatthew Barth 
36*014f07c7SMatthew Barth } // namespace utility
37*014f07c7SMatthew Barth } // namespace control
38*014f07c7SMatthew Barth } // namespace fan
39*014f07c7SMatthew Barth } // namespace phosphor
40