-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathMovingAvgFilter.h
111 lines (94 loc) · 2.57 KB
/
MovingAvgFilter.h
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <iostream>
#include <stddef.h>
#include <assert.h>
#include <ipp.h>
using std::cout;
using std::endl;
class SMA
{
public:
SMA(int period) :
period(period), window(new Ipp32f[period]), head(NULL), tail(NULL),
total(0)
{
assert(period >= 1);
}
~SMA()
{
delete[] window;
}
// Adds a value to the average, pushing one out if nescessary
void add(Ipp32f val)
{
// Special case: Initialization
if (head == NULL)
{
head = window;
*head = val;
tail = head;
inc(tail);
total = val;
return;
}
// Were we already full?
if (head == tail)
{
// Fix total-cache
total -= *head;
// Make room
inc(head);
}
// Write the value in the next spot.
*tail = val;
inc(tail);
// Update our total-cache
total += val;
}
// Returns the average of the last P elements added to this SMA.
// If no elements have been added yet, returns 0.0
Ipp32f avg(Ipp32f numer) const
{
ptrdiff_t size = this->size();
if (size == 0)
{
return 0; // No entries => 0 average
}
return total * numer;
}
void movAvg(Ipp32f *data, int len, Ipp32f numCoefficient, Ipp32f *out)
{
int counter = 0;
for (Ipp32f *itr = data; itr < (data + len); itr++)
{
this->add(*itr);
//cout << "Added " << *itr << " avg: " << this->avg(numCoefficient) << endl;
out[counter] = this->avg(numCoefficient);
counter++;
}
}
private:
int period;
Ipp32f *window; // Holds the values to calculate the average of.
// Logically, head is before tail
Ipp32f *head; // Points at the oldest element we've stored.
Ipp32f *tail; // Points at the newest element we've stored.
Ipp32f total; // Cache the total so we don't sum everything each time.
// Bumps the given pointer up by one.
// Wraps to the start of the array if needed.
void inc(Ipp32f *&p)
{
if (++p >= window + period)
{
p = window;
}
}
// Returns how many numbers we have stored.
ptrdiff_t size() const
{
if (head == NULL)
return 0;
if (head == tail)
return period;
return (period + tail - head) % period;
}
};