#if 0 This adds a generic exponentially weighted moving average function. This implementation makes use of a structure which keeps a scaled up internal representation to reduce rounding errors. The idea for this implementation comes from the rt2x00 driver (rt2x00link.c) and i would like to use it in several places in the mac80211 and ath5k code. #endif #ifndef _LINUX_AVERAGE_H #define _LINUX_AVERAGE_H #define AVG_FACTOR 1000 struct avg_val { int value; int internal; }; /** * moving_average - Exponentially weighted moving average * @avg: average structure * @val: current value * @samples: number of samples * * This implementation make use of a struct avg_val to prevent rounding * errors. */ static inline struct avg_val moving_average(const struct avg_val avg, const int val, const int samples) { struct avg_val ret; ret.internal = avg.internal ? (((avg.internal * (samples - 1)) + (val * AVG_FACTOR)) / samples) : (val * AVG_FACTOR); ret.value = ret.internal / AVG_FACTOR; return ret; } #endif /* _LINUX_AVERAGE_H */ #include int main(int argc, char *argv[]) { struct avg_val avg = {}; int count; int val; int sum = 0; for (count = 1; count <= 10; count++) { val = count + count/2; sum += val; avg = moving_average(avg, val, count); printf("count: %d, val: %d, sum: %d, avg: %d, internal: %d\n", count, val, sum, avg.value, avg.internal); } return 0; }