我有一个输入的模拟值流,需要在1000个样本的移动窗口内对它进行一些基本统计。我不希望每次添加样本时都遍历并汇总整个窗口(没有处理时间)。我写了下面的代码,它的工作,但当索引回滚到零,我显然需要做些什么,这样我就不会在数据中有一个很大的不连续性,但我不能为我的生活弄清楚我错过了什么。
void stats(double in, stat_s *out)
{
static uint32_t index = 1;
double sum = 0, sum1 = 0;
double differential = 0;
double newDSquared = 0;
double newMean = 0;
out->arr[index%wnd_sz] = in;//array index values cycle within window size
if(index!=0) differential = (in - out->mean) / index;
else {
//Do something here since we rolled back to the head of the index
}
newMean = out->mean + differential;
double dSquaredIncrement = (in - newMean) * (in - out->mean);
if(dSquaredIncrement>0) newDSquared = out->dSquared + dSquaredIncrement;
out->mean = newMean;
out->dSquared = newDSquared;
if(index!=0) out->variance = out->dSquared / index;
out->std_dev = sqrt(out->variance);
out->max = out->mean + out->std_dev;
out->min = out->mean - out->std_dev;
//prevent overflow for long running sessions.
if(index < 3*wnd_sz) index++;
else {
index = 0;
}
}
运行时,数据如下所示:
您可以看到,当索引重置为0时,最后一个波形上有一个较大的跳跃。
1条答案
按热度按时间k97glaaz1#
好吧,我自己算出来了。@Nelfeal关于只需要当前计算所基于的值的数量的评论是我所遗漏的。下面是使其工作的两个函数:
首先是循环缓冲区:
其次是实际的统计工作。这需要分为三个状态:
1.缓冲区中无数据的启动
1.缓冲区有数据但未满
1.缓冲区已满