d5da01ce0695bbf2e6e7bf0b7f9fc919f2678e2a
[platform/core/ml/nnfw.git] / compiler / record-minmax / include / RecordFunction.h
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <vector>
18 #include <cassert>
19 #include <algorithm>
20 #include <cmath>
21 #include <limits>
22 #include <stdexcept>
23
24 namespace record_minmax
25 {
26
27 /**
28  * @brief  getNthPercentile calculates the n-th percentile of input vector (0.0 <= n <= 100.0)
29  *         linear interpolation is used when the desired percentile lies between two data points
30  */
31 float getNthPercentile(std::vector<float> &vector, float percentile)
32 {
33   if (percentile < 0 || percentile > 100)
34     throw std::runtime_error("Percentile must be ranged from 0 to 100");
35
36   if (vector.empty())
37     throw std::runtime_error("Percentile must take a non-empty vector as an argument");
38
39   if (vector.size() == 1)
40     return vector[0];
41
42   std::vector<float> copy;
43   copy.assign(vector.begin(), vector.end());
44   std::sort(copy.begin(), copy.end());
45
46   if (percentile == 0.0)
47     return copy.front();
48
49   if (percentile == 100.0)
50     return copy.back();
51
52   int index = static_cast<int>(std::floor((copy.size() - 1) * percentile / 100.0));
53
54   float percent_i = static_cast<float>(index) / static_cast<float>(copy.size() - 1);
55   float fraction =
56     (percentile / 100.0 - percent_i) / ((index + 1.0) / (copy.size() - 1.0) - percent_i);
57   float res = copy[index] + fraction * (copy[index + 1] - copy[index]);
58   return res;
59 }
60
61 /**
62  * @brief  getMovingAverage calculates the weighted moving average of input vector
63  *         The initial value is the minimum (or maximum) value of the first batch of the vector
64  */
65 float getMovingAverage(const std::vector<float> &vector, const float alpha,
66                        const uint8_t batch_size, bool is_min)
67 {
68   assert(!vector.empty());
69   assert(alpha >= 0.0 && alpha <= 1.0);
70   assert(batch_size > 0);
71
72   auto getBatchMinOrMax = [&](uint32_t start_index) {
73     assert(start_index < vector.size());
74
75     float res = is_min ? std::numeric_limits<float>::max() : std::numeric_limits<float>::lowest();
76     for (uint32_t offset = 0; offset < batch_size; offset++)
77     {
78       uint32_t index = start_index + offset;
79       if (index >= vector.size())
80         break;
81
82       if (is_min)
83       {
84         res = vector[index] < res ? vector[index] : res;
85       }
86       else
87       {
88         res = vector[index] > res ? vector[index] : res;
89       }
90     }
91     return res;
92   };
93
94   float curr_avg = getBatchMinOrMax(0);
95   for (uint32_t i = batch_size; i < vector.size(); i += batch_size)
96   {
97     curr_avg = curr_avg * alpha + getBatchMinOrMax(i) * (1.0 - alpha);
98   }
99   return curr_avg;
100 }
101
102 } // namespace record_minmax