-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathEwmaT
82 lines (71 loc) · 1.99 KB
/
EwmaT
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
* Filter template that allows restriction to only one specific data type, such as uint32_t. Avoiding floating point arithmetics
* can significantly decrease code footprint, especially in embeded devices, such as Arduino or STM32.
*
* If you want to create a filter for integers, with an alpha value of 0.03, you will just do the following:
*
* EwmaT <int> filter(3, 100)
*
*/
template <typename T>
class EwmaT {
public:
/*
* Creates a filter with a defined initial output.
*/
EwmaT(T alpha, int alphaScale);
/*
* Creates a filter with a defined initial output.
*/
EwmaT(T alpha, int alphaScale, T initialOutput);
void reset();
T output();
/*
* Specifies a reading value.
* @returns current output
*/
T filter(T input);
private:
void init(T alpha, int alphaScale, T initialOutput);
/*
* Smoothing factor, in range [0,alphaScale]. Higher the value - less smoothing (higher the latest reading impact).
*/
T alpha = 0;
T outputScaled;
int alphaScale;
bool hasInitial;
};
template <typename T>
EwmaT<T>::EwmaT(T alpha, int alphaScale) {
init(alpha, alphaScale, 0);
this->hasInitial = false;
}
template <typename T>
EwmaT<T>::EwmaT(T alpha, int alphaScale, T initialOutput) {
init(alpha, alphaScale, initialOutput);
}
template <typename T>
void EwmaT<T>::init(T alpha, int alphaScale, T initialOutput) {
this->alpha = alpha;
this->alphaScale = alphaScale;
this->outputScaled = initialOutput * alphaScale;
this->hasInitial = true;
}
template <typename T>
void EwmaT<T>::reset() {
this->hasInitial = false;
}
template <typename T>
T EwmaT<T>::filter(T input) {
if (hasInitial) {
outputScaled = alpha * input + (alphaScale - alpha) * outputScaled / alphaScale;
} else {
outputScaled = input * alphaScale;
hasInitial = true;
}
return output();
}
template <typename T>
T EwmaT<T>::output() {
return (outputScaled + alphaScale / 2) / alphaScale;
}