How to efficiently compute average on the fly (moving average)?

为君一笑 提交于 2019-11-27 10:28:20

问题


I come up with this

n=1;
curAvg = 0;
loop{
  curAvg = curAvg + (newNum - curAvg)/n;
  n++;
}

I think highlights of this way are:
- It avoids big numbers (and possible overflow if you would sum and then divide)
- you save one register (not need to store sum)

The trouble might be with summing error - but I assume that generally there shall be balanced numbers of round up and round down so the error shall not sum up dramatically.

Do you see any pitfalls in this solution? Have you any better proposal?


回答1:


Your solution is essentially the "standard" optimal online solution for keeping a running track of average without storing big sums and also while running "online", i.e. you can just process one number at a time without going back to other numbers, and you only use a constant amount of extra memory. If you want a slightly optimized solution in terms of numerical accuracy, at the cost of being "online", then assuming your numbers are all non-negative, then sort your numbers first from smallest to largest and then process them in that order, the same way you do now. That way, if you get a bunch of numbers that are really small about equal and then you get one big number, you will be able to compute the average accurately without underflow, as opposed to if you processed the large number first.




回答2:


The formula above is nonsense. Simple maths and precision would dictate:

n is the iteration counter, AV is running average, newVal is new value

initialization n=0, AV=0

( (AV * n) + newVal ) / (n+1) = AV

There is no shortcut, you have to have all the numbers and divide them by the number of iterations, however you can rebuild one of the numbers by knowing which iteration it is, it is a tossup of keeping a running total or re-calculating it. The time to re-calculate is at a high cost the cost of storing a number probably a low cost in terms of memory and the code to re-calculate would certainly be more than the memory location to hold the total and the iteration.



来源:https://stackoverflow.com/questions/28820904/how-to-efficiently-compute-average-on-the-fly-moving-average

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!