1

I have used the 'mean' function on GSL which proved to be more accurate than my naive implementation. I haven't found a 'sum' function though, I'm using 'mean'*N instead, but I think it would be cleaner if I use a proper summing function.

I'm summing a huge quantity of numbers, I and was wondering this to avoid if possible implementing a stable summing algorithm.

Thanks in advance.

4

2 回答 2

1

简短回答:更好的求和方法是Kahan summation algorithm这个答案更正表明

“它具有与朴素求和相同的算法复杂度;它将大大提高求和的准确性。”,并且还给出了 C++ 的实现。

仅当数组元素的大小差异很大或者您确实需要 double 原则上可以提供的 16 位精度时(很少见),才需要 Kahan 求和。

所以,在用 C 编码 kahan 求和之前,你应该做一些检查。鉴于 GSL 的实现gsl_stats_mean

(GSL 1.16 源代码)

  /* 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);
  }

如果您的数字在幅度上确实存在很大差异(您的高度可变的数字和平均值之间存在直接的总和,而平均值的幅度变化缓慢),我无法立即看到这将避免精度损失。)。一个很好的检查是在使用您的幼稚实现/gsl 计算总和/平均值之前对您的数组进行排序。

编辑 1:警告,如果打开优化,c = (t - sum) - y可能会被优化。c = 0

于 2013-10-23T06:01:06.270 回答
1

一个有时使用的技巧是使用cblas_ddot函数并用一个向量计算数据的点积。这将有效地计算数据的总和。

于 2013-10-22T15:57:15.827 回答