【问题标题】:How to get weighted average where latest value is weighted twice as all previous?如何获得加权平均值,其中最新值的权重是以前的两倍?
【发布时间】:2016-12-21 18:25:27
【问题描述】:

我以前用过这个,但就是想不起来了,到处都找不到。

这是一个运行平均值,其中最新值的权重是所有先前值(组合)的两倍,因此随着时间的推移,最旧值的影响越来越小。而且我没有足够的内存来存储旧值。

平均:

int sum=0;
int n = 0;
float aver = 0;
for(;;){
  float new_value = some_function();
  sum += new_value;
  ++n;
  aver = sum / n;  
}

但是如何获得一个平均值,其中 new_value 的权重是之前平均值的两倍?

float aver = 0;
for(;;){
  float new_value = some_function();
  aver = aver * ??? + new_value * ???;

}

【问题讨论】:

  • aver = (aver + 2 * new_value) / 3;
  • “所有先前值的权重的两倍”是指所有其他值的 组合 权重的两倍还是 最后一个值的两倍 价值?
  • 上一个值的两倍。
  • “运行平均值”将使用第一个评论中的过滤器,或者使用环形缓冲区并将其值相加,在这种情况下,您将最近的值相加两次并除以 (n + 1) .当然,您不会将n 增加到超出环形缓冲区大小。
  • 您能否展示一些样本数据的预期结果?假设传入的值是这 10 个:1.11 8.63 4.31 5.54 7.79 8.35 3.79 6.40 3.15 6.29 — 您希望计算(打印)什么?

标签: c algorithm weighted-average


【解决方案1】:

一个运行平均值,其中最新值的权重是所有先前值的两倍,...

我如何获得一个平均值,其中 new_value 的权重是之前平均值的两倍?

计算总和和最新的特殊平均值。

int sum = 0;
int n = 0;
float average_special = 0.0;
for(;;) {
  float new_value = some_function();
  sum += new_value;
  ++n;
  average_special = (sum + new_value) / (n+1);  
}

【讨论】:

  • @EugeneSh。鉴于 OP 想要基于 all previous 的答案,可疑溢出是一个问题,这意味着所有样本的总和不是范围问题。如果有的话,更有可能导致精度问题。确实,运行平均值更像average = (1-tau)*average + tau*sample Low-pass_filter,但 OP 并没有问这个问题
  • 但是,在我看来,随着时间的推移,new_value 对 average_special 的影响会越来越小。我需要最新的值才能使平均影响与所有以前的值一样。
  • EugeneSh:看起来比较熟悉。所以在:平均=(1-tau)*平均+tau*样本那么tau是一个加权因子? tau=0.5:样品重量与平均值相同。 tau=2/3:那么样本的平均权重是两倍?甜!
  • @DougNull 在“最新值平均影响所有以前的值”中存在歧义。 “所有先前值的平均值”在sum += new_value; 之前是sum/n,没有解决这个问题。看来您需要两件事,一些输出具有“两次影响 平均值。output = (2*new_value + sum/n)/3 和正在运行的sum 稍后计算平均值。
  • @DougNull 但在更大的意义上,您要求的可能不是需要的output = (1-tau)*output + tau*sample 是非常标准的代码(可能对整数数学进行了一些调整)并且似乎是您需要的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-16
  • 2017-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多