什么是数值计算平均值的最佳方法

时间:2011-09-26 08:25:23

标签: c++ numerical-methods

计算平均值的最佳方法是什么?有了这个问题,我想知道在数值意义上用于计算平均值的算法是最好的。它应该具有最小的舍入误差,不应对上溢或下溢等敏感。

谢谢。


附加信息:首选增量方法,因为值的数量可能不适合RAM(对大于4 GB的文件进行多次并行计算)。

6 个答案:

答案 0 :(得分:8)

如果您想要O(N)算法,请查看Kahan summation

答案 1 :(得分:6)

您可以查看http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.3535(Nick Higham,“浮点求和的准确性”,SIAM Journal of Scientific Computation,1993)。

如果我没记错的话,如果所有数字都是正数,则补偿求和(Kahan求和)是好的,至少与排序它们并按升序添加它们一样好(除非有非常多的数字)。如果有些数字为正数且有些数字为负数,则故事要复杂得多,以便取消。在这种情况下,有一个参数可以按降序添加它们。

答案 2 :(得分:4)

只是为了进一步讨论添加一个可能的答案:

逐步计算每一步的平均值:

  

AVG_n = AVG_(n-1)*(n-1)/ n + VALUE_n / n

或成对组合

  

AVG_(n_a + n_b)=(n_a * AVG_a + n_b * AVG_b)/(n_a + n_b)

(我希望公式足够清晰)

答案 3 :(得分:3)

按数量级的升序排序数字。总结它们,首先是低幅度。除以计数。

答案 4 :(得分:2)

一篇很晚的帖子,但由于我没有足够的声誉来发表评论,@Dave 的方法是 Gnu Scientific Library 使用的方法(截至 2020 年 12 月)。

这是从mean_source.c中提取的代码:

double FUNCTION (gsl_stats, mean) (const BASE data[], const size_t stride, const size_t size)
{
/* Compute the arithmetic mean of a dataset using the recurrence relation mean_(n) = mean(n-1) + (data[n] - mean(n-1))/(n+1)   */

long double mean = 0;
size_t i;

for (i = 0; i < size; i++)
{
  mean += (data[i * stride] - mean) / (i + 1);
}

return mean;
}

GSL 使用相同的算法来计算方差,毕竟它只是给定数字的平方差的平均值。

答案 5 :(得分:0)

我总是使用以下伪代码:

float mean=0.0; // could use doulbe
int n=0;  // could use long

for each x in data:
    ++n;
    mean+=(x-mean)/n;

我没有关于其稳定性的正式证据,但你可以看到我们不会遇到数值溢出问题,假设数据值表现良好。它在Knuth的计算机编程艺术

中被提及