0

在 C++ 中,什么是计算不完整 gamma 函数的快速方法,或者至少是它的“良好”近似值?

背景

我最终需要计算的

给定许多伯努利轨迹 N,成功概率为 p,我最终试图计算获得最多 k 次成功的概率,作为 k 的函数。累积二项式分布 F(k,N,p) 给出了这个概率。

对速度的需求

我需要每秒计算几十万个这些累积概率。对于较大的 N,通过直接求和计算累积二项式分布的计算量非常大。使用不完全 beta 函数要好得多,但仍然是计算量很大的。

可利用的约束

我希望来自应用程序域的以下约束可以帮助加快计算速度:

  • p < 0.01(分布总是很偏斜)
  • N > 50

泊松近似

在 Excel 中进行了一些实验后,我了解到泊松近似在上述条件下非常出色。即,在感兴趣的条件下,k 处的 B(N,p) 与 k 处的 Pois(Np) 几乎相同。这意味着我只需要 2 个变量的函数,不再需要 3 个。

我知道累积泊松分布可以用不完全伽马函数来计算,从 cephes 库中的源代码来看,它似乎比原来的不完全 beta 函数要简单得多。在没有泊松近似的情况下计算。但它仍然不是很简单,是一个迭代的数值计算。所以现在我正在寻找一种快速计算不完全伽马函数的方法。我想知道是否没有一个封闭形式的表达式可以很好地近似它。

所需精度

在积分/概率上 20% 的相对误差是完全可以接受的(从每个 k 考虑,在两个方向上)。

我考虑过直接使用 Poisson CDF 的插值查找表,但均匀间隔的域点可能不太理想,并且域也必须限制为任意矩形。我希望理想地找到具有大量调整参数的分析函数。

4

1 回答 1

0

我没有使用 Gamma 函数,而是炮制了这种将泊松变量转换为标准正态变量的近似值:

float poisson_z(float x, float mu){
    static const float twoThirds = 2.0f/3.0f;
    float w = sqrt((x+0.5f)/mu) - 1.0f;
    float coeff = w>=0.0f ? 0.085f : 0.15f;
    return (x-mu+twoThirds)/sqrtf(mu*(1.0f+w*(0.68f+w*coeff)));
}

标准正态分布不乏近似值。

于 2014-07-15T23:12:18.373 回答