1 /*
2  *  Copyright 2019 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef RTC_BASE_NUMERICS_EVENT_BASED_EXPONENTIAL_MOVING_AVERAGE_H_
12 #define RTC_BASE_NUMERICS_EVENT_BASED_EXPONENTIAL_MOVING_AVERAGE_H_
13 
14 #include <cmath>
15 #include <cstdint>
16 #include <limits>
17 #include "absl/types/optional.h"
18 
19 namespace rtc {
20 
21 /**
22  * This class implements exponential moving average for time series
23  * estimating both value, variance and variance of estimator based on
24  * https://en.wikipedia.org/w/index.php?title=Moving_average&section=9#Application_to_measuring_computer_performance
25  * with the additions from nisse@ added to
26  * https://en.wikipedia.org/wiki/Talk:Moving_average.
27  *
28  * A sample gets exponentially less weight so that it's 50%
29  * after |half_time| time units.
30  */
31 class EventBasedExponentialMovingAverage {
32  public:
33   // |half_time| specifies how much weight will be given to old samples,
34   // see example above.
35   explicit EventBasedExponentialMovingAverage(int half_time);
36 
37   void AddSample(int64_t now, int value);
38 
GetAverage()39   double GetAverage() const { return value_; }
GetVariance()40   double GetVariance() const { return sample_variance_; }
41 
42   // Compute 95% confidence interval assuming that
43   // - variance of samples are normal distributed.
44   // - variance of estimator is normal distributed.
45   //
46   // The returned values specifies the distance from the average,
47   // i.e if X = GetAverage(), m = GetConfidenceInterval()
48   // then a there is 95% likelihood that the observed variables is inside
49   // [ X +/- m ].
50   double GetConfidenceInterval() const;
51 
52   // Reset
53   void Reset();
54 
55   // Update the half_time.
56   // NOTE: resets estimate too.
57   void SetHalfTime(int half_time);
58 
59  private:
60   double tau_;
61   double value_ = std::nan("uninit");
62   double sample_variance_ = std::numeric_limits<double>::infinity();
63   // This is the ratio between variance of the estimate and variance of samples.
64   double estimator_variance_ = 1;
65   absl::optional<int64_t> last_observation_timestamp_;
66 };
67 
68 }  // namespace rtc
69 
70 #endif  // RTC_BASE_NUMERICS_EVENT_BASED_EXPONENTIAL_MOVING_AVERAGE_H_
71