GNU 科学图书馆 (GSL) 的总结

问题描述 投票:0回答:2

我在 GSL 上使用了 'mean' 函数,事实证明它比我天真的实现更准确。虽然我还没有找到“求和”函数,但我使用“mean”*N代替,但我认为如果我使用适当的求和函数,它会更干净。

我正在对大量数字进行求和,我想知道这一点,以避免如果可能的话实现稳定的求和算法。

c gsl
2个回答
1
投票

一个有时使用的技巧是使用

cblas_ddot
函数并计算数据与 1 向量的点积。这将有效地计算您的数据总和。


1
投票

简短回答:更好的求和方法是Kahan求和算法此答案更正指出

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

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

因此,在用 C 语言编写 kahan 求和之前,您应该做一些检查。鉴于

gsl_stats_mean
的 GSL 实现是

(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

© www.soinside.com 2019 - 2024. All rights reserved.