Source: lib/abr/ewma.js

  1. /*! @license
  2. * Shaka Player
  3. * Copyright 2016 Google LLC
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. goog.provide('shaka.abr.Ewma');
  7. goog.require('goog.asserts');
  8. /**
  9. * @summary
  10. * This class computes an exponentionally-weighted moving average.
  11. */
  12. shaka.abr.Ewma = class {
  13. /**
  14. * @param {number} halfLife The quantity of prior samples (by weight) used
  15. * when creating a new estimate. Those prior samples make up half of the
  16. * new estimate.
  17. */
  18. constructor(halfLife) {
  19. goog.asserts.assert(halfLife > 0, 'expected halfLife to be positive');
  20. /**
  21. * Larger values of alpha expire historical data more slowly.
  22. * @private {number}
  23. */
  24. this.alpha_ = Math.exp(Math.log(0.5) / halfLife);
  25. /** @private {number} */
  26. this.estimate_ = 0;
  27. /** @private {number} */
  28. this.totalWeight_ = 0;
  29. }
  30. /**
  31. * Takes a sample.
  32. *
  33. * @param {number} weight
  34. * @param {number} value
  35. */
  36. sample(weight, value) {
  37. const adjAlpha = Math.pow(this.alpha_, weight);
  38. const newEstimate = value * (1 - adjAlpha) + adjAlpha * this.estimate_;
  39. if (!isNaN(newEstimate)) {
  40. this.estimate_ = newEstimate;
  41. this.totalWeight_ += weight;
  42. }
  43. }
  44. /**
  45. * @return {number}
  46. */
  47. getEstimate() {
  48. const zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_);
  49. return this.estimate_ / zeroFactor;
  50. }
  51. };