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