Home Reference Source

src/utils/ewma.ts

  1. /*
  2. * compute an Exponential Weighted moving average
  3. * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
  4. * - heavily inspired from shaka-player
  5. */
  6.  
  7. class EWMA {
  8. public readonly halfLife: number;
  9. private alpha_: number;
  10. private estimate_: number;
  11. private totalWeight_: number;
  12.  
  13. // About half of the estimated value will be from the last |halfLife| samples by weight.
  14. constructor(halfLife: number, estimate: number = 0, weight: number = 0) {
  15. this.halfLife = halfLife;
  16. // Larger values of alpha expire historical data more slowly.
  17. this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0;
  18. this.estimate_ = estimate;
  19. this.totalWeight_ = weight;
  20. }
  21.  
  22. sample(weight: number, value: number) {
  23. const adjAlpha = Math.pow(this.alpha_, weight);
  24. this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_;
  25. this.totalWeight_ += weight;
  26. }
  27.  
  28. getTotalWeight(): number {
  29. return this.totalWeight_;
  30. }
  31.  
  32. getEstimate(): number {
  33. if (this.alpha_) {
  34. const zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_);
  35. if (zeroFactor) {
  36. return this.estimate_ / zeroFactor;
  37. }
  38. }
  39. return this.estimate_;
  40. }
  41. }
  42.  
  43. export default EWMA;