y[i] := ß * x[i] + (1-ß) * y[i-1]
From Wiki: This discrete-time implementation of a simple RC low-pass filter is the exponentially weighted moving average (aka Exponential smoothing)
Exponential smoothing: y[i] := y[i-1] + α * (x[i] - y[i-1]) where α = (1-ß) (from above)
#define ALPHA_PERCENT 60 int16_t exponential_smoothing(int16_t input, int16_t old_value) { int32_t val = old_value; int32_t diff = input - old_value; val += (ALPHA_PERCENT * diff) / 100; return val; }
aka moving average / rolling average / running average
#define LPA_NUM 10 static int16_t lpa_buf[LPA_NUM]; void low_pass_average_init(int16_t init_value) { for (int i = 0; i < sizeof(lpa_buf)/sizeof(lpa_buf[0]); i++) { lpa_buf[i] = init_value; } } int16_t low_pass_average(int16_t input) { int32_t sum = 0; for (unsigned int i = (LPA_NUM)-1; i > 0; --i) { lpa_buf[i] = lpa_buf[i-1]; sum += lpa_buf[i]; } sum += input; lpa_buf[0] = input; return sum/LPA_NUM; }
Time-weighted moving average LWMA - Linearly Weighted Moving Average
#define LPA_NUM 10 static int16_t wma_buf[LPA_NUM]; static int16_t ma_w[LPA_NUM] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; void mag_moving_average_init(int16_t init_value) { for (int i = 0; i < sizeof(ma_buf)/sizeof(ma_buf[0]); i++) { wma_buf[i] = init_value; } } nt16_t mag_weighted_moving_average(int16_t input) { int32_t sum = 0; int32_t w_sum = 0; for (unsigned int i = (LPA_NUM)-1; i > 0; --i) { wma_buf[i] = wma_buf[i-1]; sum += wma_buf[i] * ma_w[i]; w_sum += ma_w[i]; } wma_buf[0] = input; sum += wma_buf[0] * ma_w[0]; w_sum += ma_w[0]; return sum / w_sum; }
aka: anomaly detection