计算存储在向量中的值流的移动平均值

时间:2015-05-14 09:00:37

标签: c++ stream moving-average

我有一个结构向量,用于存储以不同间隔到达的值流。该结构由两个元素组成,一个用于值,另一个用于记录值到达时的时间。

struct Data {
    Time timeOfArrival;
    Time value;
}cd;

让我们说在另一个线程中,我想计算在过去10(比如)秒内到达的值的移动平均值。所以在一个线程中正在填充向量,而在另一个线程中我想要计算移动平均值。

2 个答案:

答案 0 :(得分:1)

我将如何做到这一点。为简单起见,我重新定义了数据如下:

struct Data
{
    int timeOfArrival;
    int value;
};

您要求的一种方法是使用循环缓冲区,只存储移动平均线所需的数据量。

enum { MOVING_AVG_SIZE = 64, };  // number of elements that you use for your moving average

std::vector<Data> buffer(MOVING_AVG_SIZE);
std::vector<Data>::iterator insertIt = buffer.begin();

// saving to circular buffer
Data newData;

++insertIt
if (insertIt == buffer.end()) insertIt = buffer.begin();
*insertIt = newData;

// average
int sum = 0;
for (std::vector<Data>::const_iterator it = buffer.begin(); it != buffer.end(); ++it)
{
    sum += it->value;
}
float avg = sum / (float)buffer.size();

如果你没有循环缓冲区并且只是不断向向量添加值,那么你可以获得计算移动平均线所需的最后一个元素数。

// saving to circular buffer
Data newData;
buffer.push_back(newData);

// average
// this algorithm calculates the moving average even if there is not enough samples in the buffer for the "10 s" 
std::vector<Data>::const_reverse_iterator it = buffer.rbegin();
int i;
int sum = 0;
for (i = 0; i < MOVING_AVG_SIZE || it == buffer.rend(); ++i)
{
    sum += it->value;
}
float avg = sum / (float)i;

答案 1 :(得分:0)

由于您已经确定一个线程将始终填充,另一个线程将执行移动平均线。然后你可以这样做:

保持一个结构包含两个元素RunningSum,而不包含向量中的项目。

编写一个循环,删除超过10秒的元素,并从RunningSum中扣除它们的值。向量中的所有元素都按照到达时间进行排序,因此您无需迭代整个向量。 添加总和尚未添加的新元素的值。

您需要一种方法来消除已添加(用于总和)的项目和尚未求和的项目。您可以为此使用布尔值或将它们放在新的dataStructure中(类的内部)。

保持元素数量并计算平均值。