1
\$\begingroup\$

I'm wanting to calculate exponential moving averages of a variable, distance. Is the logic (and math) correct in the below code?

time and lastTime are millisecond-precise timestamps in seconds – the former is the current time, the latter is the time of the last calculations.

lastA etc are the exponential moving averages from the last calculations.

a etc will be left with the calculated exponential moving averages.

var distance = ...;
var a = Math.pow(1.16, -(time-lastTime)),
    b = Math.pow(1.19, -(time-lastTime)),
    c = Math.pow(1.22, -(time-lastTime)),
    d = Math.pow(1.26, -(time-lastTime)),
    e = Math.pow(1.30, -(time-lastTime)),
    f = Math.pow(1.35, -(time-lastTime)),
    g = Math.pow(1.40, -(time-lastTime));
a = a*lastA + (1-a)*distance;
b = b*lastB + (1-b)*distance;
c = c*lastC + (1-c)*distance;
d = d*lastD + (1-d)*distance;
e = e*lastE + (1-e)*distance;
f = f*lastF + (1-f)*distance;
g = g*lastG + (1-g)*distance;
\$\endgroup\$
0
4
\$\begingroup\$

This is border line a bad question, as not enough code is given to properly review it.

The variables a -> g look terrible, I would create an array with the numbers you need:

var dataPoints = [1.16,1.19,1.22,1.26,1.30,1.35,1.40];

Then I would would loop over those points and create an averages object

var averages = {},
    value, x;
for(var i = 0, length = dataPoints.length ; i < length ; i++ ){
  value = dataPoints[i];
  x = Math.pow(value, -(time-lastTime));
  averages[value] = x * lastAverages[value] + (1-x) * distance;
}

I cannot tell whether the math is correct, if it is not correct, then this question does not belong here :)

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Why use objects for storage, though? Just use plain arrays for averages and lastAverages. Indices will match the dataPoints array. Using numbers as property names is iffy, as they'll get treated as strings and whatnot. \$\endgroup\$
    – Flambino
    Feb 20 '14 at 1:42
  • 1
    \$\begingroup\$ @200_success I think the code conveys my point. The original code cannot run, so I cannot test and fix mistakes. \$\endgroup\$
    – konijn
    Feb 20 '14 at 13:24
2
\$\begingroup\$

Either I'm confused by your notation, or you may have implemented something completely different from an exponential moving average, which is traditionally defined as

\$S_{t} = \alpha Y_{t-1} + (1-\alpha) S_{t-1}\$

where

  • \$\alpha\$ is the decay rate
  • \$Y_{t}\$ is the value at time \$t\$
  • \$S_{t}\$ is the exponential moving average at time \$t\$.

How do your variables correspond to those in the definition? Let's just consider one of your letters instead of all seven:

var distance = ...;
var a = Math.pow(1.16, -(time-lastTime));
a = a*lastA + (1-a)*distance;

I'm guessing

  • a corresponds to \$\alpha\$, and you adjust the decay per timeslice based on the duration of the timeslice
  • lastA corresponds to \$Y_{t-1}\$
  • distance corresponds to \$S_{t-1}\$

But then, I'm confused:

  1. What's the purpose of the seven letters ag? To track the results using multiple decay rates? If so, wouldn't the different decay rates result in a different series St for each decay rate?
  2. Why do all seven cases all share the same distance — isn't it the point to have a different distance series for each case?
  3. Why do you assign the final result to a (= the decay rate) rather than to distance or something?
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.