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