1 #include "calculate.hpp"
2 
3 #include <limits>
4 
5 namespace phosphor::virtual_sensor
6 {
7 
8 double calculateModifiedMedianValue(std::vector<double>& values)
9 {
10     size_t size = values.size();
11     std::sort(values.begin(), values.end());
12     switch (size)
13     {
14         case 2:
15             /* Choose biggest value */
16             return values.at(1);
17         case 0:
18             return std::numeric_limits<double>::quiet_NaN();
19         default:
20             /* Choose median value */
21             if (size % 2 == 0)
22             {
23                 // Average of the two middle values
24                 return (values.at(size / 2) + values.at(size / 2 - 1)) / 2;
25             }
26             else
27             {
28                 return values.at((size - 1) / 2);
29             }
30     }
31 }
32 
33 double calculateMaximumValue(std::vector<double>& values)
34 {
35     auto maxIt = std::max_element(values.begin(), values.end());
36     if (maxIt == values.end())
37     {
38         return std::numeric_limits<double>::quiet_NaN();
39     }
40     return *maxIt;
41 }
42 
43 double calculateMinimumValue(std::vector<double>& values)
44 {
45     auto maxIt = std::min_element(values.begin(), values.end());
46     if (maxIt == values.end())
47     {
48         return std::numeric_limits<double>::quiet_NaN();
49     }
50     return *maxIt;
51 }
52 
53 std::map<Interface, CalculationFunc> calculationIfaces{
54     {"xyz.openbmc_project.Configuration.Maximum", calculateMaximumValue},
55     {"xyz.openbmc_project.Configuration.Minimum", calculateMinimumValue},
56     {"xyz.openbmc_project.Configuration.ModifiedMedian",
57      calculateModifiedMedianValue}};
58 
59 } // namespace phosphor::virtual_sensor
60