|
For dynamic alpha, start by pretending the new incoming, windowed data doesn't exist. Look at your old data. How quickly do you want it to disappear? It'll have some formula like e^-(bt) for some constant b governing what proportion from 0 to 1 of that data still remains. So...T seconds have elapsed since your last frame, and you have a new data point you'd like to incorporate into your EMA (and, for this problem, that data point is T itself). You keep e^-(bT) of the old data, 1 minus that of the new data, and you're done. Alpha is indeed 1-e^-(b * cur_spf) for some constant b, just like the AI said. Which b do you choose though? I usually prefer to think of it in terms of half lives. Let H be your desired half life, and set 1-e^-(bH) equal to 1/2. You get b=log(2)/H. That's similar to the AI answer, but it rescales window_secs into a parameter you can actually start to reason about. The AI answer gives you a 1/e life instead, which is a less comfortable constant to mentally process. That answer also naturally generalizes to other "time" axes or denominators. Suppose you want to EMA using discrete events rather than wall-clock time. Replace T in your dynamic alpha with the discrete count of events you haven't updated the EMA with yet (e.g., if something happens every time tick you would usually take T=1, but you can increase that based on a few skipped frames or whatever if you'd like). As a fun fact, you can tailor this sort of stateless solution to have almost any decay property you'd like. Start with your favorite ODE satisfying a few properties, and this equation falls out as the step a discrete solver would take to approximate the ODE. |