summaryrefslogtreecommitdiffstats
path: root/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h')
-rw-r--r--chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h82
1 files changed, 67 insertions, 15 deletions
diff --git a/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h b/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h
index cdad0251f3f..dfda8fec072 100644
--- a/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h
+++ b/chromium/third_party/libjingle/source/talk/base/rollingaccumulator.h
@@ -42,11 +42,8 @@ template<typename T>
class RollingAccumulator {
public:
explicit RollingAccumulator(size_t max_count)
- : count_(0),
- next_index_(0),
- sum_(0.0),
- sum_2_(0.0),
- samples_(max_count) {
+ : samples_(max_count) {
+ Reset();
}
~RollingAccumulator() {
}
@@ -59,12 +56,29 @@ class RollingAccumulator {
return count_;
}
+ void Reset() {
+ count_ = 0U;
+ next_index_ = 0U;
+ sum_ = 0.0;
+ sum_2_ = 0.0;
+ max_ = T();
+ max_stale_ = false;
+ min_ = T();
+ min_stale_ = false;
+ }
+
void AddSample(T sample) {
if (count_ == max_count()) {
// Remove oldest sample.
T sample_to_remove = samples_[next_index_];
sum_ -= sample_to_remove;
sum_2_ -= sample_to_remove * sample_to_remove;
+ if (sample_to_remove >= max_) {
+ max_stale_ = true;
+ }
+ if (sample_to_remove <= min_) {
+ min_stale_ = true;
+ }
} else {
// Increase count of samples.
++count_;
@@ -73,6 +87,14 @@ class RollingAccumulator {
samples_[next_index_] = sample;
sum_ += sample;
sum_2_ += sample * sample;
+ if (count_ == 1 || sample >= max_) {
+ max_ = sample;
+ max_stale_ = false;
+ }
+ if (count_ == 1 || sample <= min_) {
+ min_ = sample;
+ min_stale_ = false;
+ }
// Update next_index_.
next_index_ = (next_index_ + 1) % max_count();
}
@@ -81,17 +103,43 @@ class RollingAccumulator {
return static_cast<T>(sum_);
}
- T ComputeMean() const {
+ double ComputeMean() const {
if (count_ == 0) {
- return static_cast<T>(0);
+ return 0.0;
+ }
+ return sum_ / count_;
+ }
+
+ T ComputeMax() const {
+ if (max_stale_) {
+ ASSERT(count_ > 0 &&
+ "It shouldn't be possible for max_stale_ && count_ == 0");
+ max_ = samples_[next_index_];
+ for (size_t i = 1u; i < count_; i++) {
+ max_ = _max(max_, samples_[(next_index_ + i) % max_count()]);
+ }
+ max_stale_ = false;
+ }
+ return max_;
+ }
+
+ T ComputeMin() const {
+ if (min_stale_) {
+ ASSERT(count_ > 0 &&
+ "It shouldn't be possible for min_stale_ && count_ == 0");
+ min_ = samples_[next_index_];
+ for (size_t i = 1u; i < count_; i++) {
+ min_ = _min(min_, samples_[(next_index_ + i) % max_count()]);
+ }
+ min_stale_ = false;
}
- return static_cast<T>(sum_ / count_);
+ return min_;
}
// O(n) time complexity.
// Weights nth sample with weight (learning_rate)^n. Learning_rate should be
// between (0.0, 1.0], otherwise the non-weighted mean is returned.
- T ComputeWeightedMean(double learning_rate) const {
+ double ComputeWeightedMean(double learning_rate) const {
if (count_ < 1 || learning_rate <= 0.0 || learning_rate >= 1.0) {
return ComputeMean();
}
@@ -106,27 +154,31 @@ class RollingAccumulator {
size_t index = (next_index_ + max_size - i - 1) % max_size;
weighted_mean += current_weight * samples_[index];
}
- return static_cast<T>(weighted_mean / weight_sum);
+ return weighted_mean / weight_sum;
}
// Compute estimated variance. Estimation is more accurate
// as the number of samples grows.
- T ComputeVariance() const {
+ double ComputeVariance() const {
if (count_ == 0) {
- return static_cast<T>(0);
+ return 0.0;
}
// Var = E[x^2] - (E[x])^2
double count_inv = 1.0 / count_;
double mean_2 = sum_2_ * count_inv;
double mean = sum_ * count_inv;
- return static_cast<T>(mean_2 - (mean * mean));
+ return mean_2 - (mean * mean);
}
private:
size_t count_;
size_t next_index_;
- double sum_; // Sum(x)
- double sum_2_; // Sum(x*x)
+ double sum_; // Sum(x) - double to avoid overflow
+ double sum_2_; // Sum(x*x) - double to avoid overflow
+ mutable T max_;
+ mutable bool max_stale_;
+ mutable T min_;
+ mutable bool min_stale_;
std::vector<T> samples_;
DISALLOW_COPY_AND_ASSIGN(RollingAccumulator);