1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
typedef struct smaint *SMAINT;
SMAINT smaint_new(int size, int initval);
int smaint_add(SMAINT sma, int value);
int smaint(SMAINT sma);
void smaint_free(SMAINT sma);
static inline double
ema(int n, double oldema, double val)
{
return (val*2.0/(n+1)) + oldema*(1-2.0/(n+1));
}
/*
Now the Exponential Moving Average (EMA) is easy to compute and defined as:
EMA(N) = VALUE(N)*K + EMA(N-1)*(1-K)
Where:
K = 2 / (N+1)
If you limit the possible values of 1/K to powers of two *AND* you
don't care if it ever decays back down to zero, then the EMA is very
easily computed using two integer adds and two shifts. For N=15, which
is a K value of (2/16 = 1/8), you get:
ema -= ema >> 3;
ema += value >> 3;
If you want the ema value to have the characteristic that it decays
down to zero (eventually), then you can do rounding arithmetic.
*/
typedef struct
{
int ema;
int k_order;
int k_inverted_minus_1;
int round;
} EMAINT;
static inline void
emaint_init(EMAINT *ema, int k_order, int initval)
{
ema->ema = initval;
ema->k_order = k_order;
ema->k_inverted_minus_1 = (1 << k_order) - 1;
ema->round = 0;
}
static inline int
emaint(EMAINT *ema, int val)
{
ema->round ^= ema->k_inverted_minus_1;
ema->ema -= (ema->ema + ema->round) >> ema->k_order;
ema->ema += val >> ema->k_order;
return ema->ema;
}
|