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