1*d83cc019SAndroid Build Coastguard Worker #ifndef EWMA_H 2*d83cc019SAndroid Build Coastguard Worker #define EWMA_H 3*d83cc019SAndroid Build Coastguard Worker 4*d83cc019SAndroid Build Coastguard Worker #include <ilog2.h> 5*d83cc019SAndroid Build Coastguard Worker 6*d83cc019SAndroid Build Coastguard Worker #define BUILD_BUG_ON(expr) 7*d83cc019SAndroid Build Coastguard Worker #define BUILD_BUG_ON_NOT_POWER_OF_2(expr) 8*d83cc019SAndroid Build Coastguard Worker 9*d83cc019SAndroid Build Coastguard Worker /* 10*d83cc019SAndroid Build Coastguard Worker * Exponentially weighted moving average (EWMA) 11*d83cc019SAndroid Build Coastguard Worker * 12*d83cc019SAndroid Build Coastguard Worker * This implements a fixed-precision EWMA algorithm, with both the 13*d83cc019SAndroid Build Coastguard Worker * precision and fall-off coefficient determined at compile-time 14*d83cc019SAndroid Build Coastguard Worker * and built into the generated helper funtions. 15*d83cc019SAndroid Build Coastguard Worker * 16*d83cc019SAndroid Build Coastguard Worker * The first argument to the macro is the name that will be used 17*d83cc019SAndroid Build Coastguard Worker * for the struct and helper functions. 18*d83cc019SAndroid Build Coastguard Worker * 19*d83cc019SAndroid Build Coastguard Worker * The second argument, the precision, expresses how many bits are 20*d83cc019SAndroid Build Coastguard Worker * used for the fractional part of the fixed-precision values. 21*d83cc019SAndroid Build Coastguard Worker * 22*d83cc019SAndroid Build Coastguard Worker * The third argument, the weight reciprocal, determines how the 23*d83cc019SAndroid Build Coastguard Worker * new values will be weighed vs. the old state, new values will 24*d83cc019SAndroid Build Coastguard Worker * get weight 1/weight_rcp and old values 1-1/weight_rcp. Note 25*d83cc019SAndroid Build Coastguard Worker * that this parameter must be a power of two for efficiency. 26*d83cc019SAndroid Build Coastguard Worker */ 27*d83cc019SAndroid Build Coastguard Worker 28*d83cc019SAndroid Build Coastguard Worker #define DECLARE_EWMA(T, name, _precision, _weight_rcp) \ 29*d83cc019SAndroid Build Coastguard Worker struct ewma_##name { \ 30*d83cc019SAndroid Build Coastguard Worker T internal; \ 31*d83cc019SAndroid Build Coastguard Worker }; \ 32*d83cc019SAndroid Build Coastguard Worker static inline void ewma_##name##_init(struct ewma_##name *e) \ 33*d83cc019SAndroid Build Coastguard Worker { \ 34*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON(!__builtin_constant_p(_precision)); \ 35*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \ 36*d83cc019SAndroid Build Coastguard Worker /* \ 37*d83cc019SAndroid Build Coastguard Worker * Even if you want to feed it just 0/1 you should have \ 38*d83cc019SAndroid Build Coastguard Worker * some bits for the non-fractional part... \ 39*d83cc019SAndroid Build Coastguard Worker */ \ 40*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON((_precision) > 30); \ 41*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \ 42*d83cc019SAndroid Build Coastguard Worker e->internal = 0; \ 43*d83cc019SAndroid Build Coastguard Worker } \ 44*d83cc019SAndroid Build Coastguard Worker static inline T \ 45*d83cc019SAndroid Build Coastguard Worker ewma_##name##_read(struct ewma_##name *e) \ 46*d83cc019SAndroid Build Coastguard Worker { \ 47*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON(!__builtin_constant_p(_precision)); \ 48*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \ 49*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON((_precision) > 30); \ 50*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \ 51*d83cc019SAndroid Build Coastguard Worker return e->internal >> (_precision); \ 52*d83cc019SAndroid Build Coastguard Worker } \ 53*d83cc019SAndroid Build Coastguard Worker static inline void ewma_##name##_add(struct ewma_##name *e, \ 54*d83cc019SAndroid Build Coastguard Worker T val) \ 55*d83cc019SAndroid Build Coastguard Worker { \ 56*d83cc019SAndroid Build Coastguard Worker const T weight_rcp = ilog2(_weight_rcp); \ 57*d83cc019SAndroid Build Coastguard Worker const T precision = _precision; \ 58*d83cc019SAndroid Build Coastguard Worker T internal = e->internal; \ 59*d83cc019SAndroid Build Coastguard Worker \ 60*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON(!__builtin_constant_p(_precision)); \ 61*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \ 62*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON((_precision) > 30); \ 63*d83cc019SAndroid Build Coastguard Worker BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \ 64*d83cc019SAndroid Build Coastguard Worker \ 65*d83cc019SAndroid Build Coastguard Worker e->internal = internal ? \ 66*d83cc019SAndroid Build Coastguard Worker (((internal << weight_rcp) - internal) + \ 67*d83cc019SAndroid Build Coastguard Worker (val << precision)) >> weight_rcp : \ 68*d83cc019SAndroid Build Coastguard Worker (val << precision); \ 69*d83cc019SAndroid Build Coastguard Worker } 70*d83cc019SAndroid Build Coastguard Worker 71*d83cc019SAndroid Build Coastguard Worker #endif /* EWMA_H */ 72