使用 Log Gamma 函数避免溢出

计算科学 C++ 浮点 特殊功能
2021-11-24 20:16:26

我必须使用 gamma 函数进行一些数值计算。我正在使用tgammaC++cmath库中包含的内容。问题是 gamma 函数内部的参数是正的而且很大,所以我总是得到一个nan.

我知道我可以lgamma在 C++ 中使用 log-gamma 函数来避免计算期间的数值溢出。问题是我不知道如何在我的情况下应用它。

例如,有类似的东西

X=Γ(a+b)Γ(ab)Γ(c)

在哪里a,bc大到足以产生溢出的整数。

我知道我可以使用日志来获取log(X)=log(Γ(a+b))+log(Γ(ab))log(Γ(c)),从该操作中获得结果并进行指数运算以获得正确的结果而不会溢出。

但是,如果我有这样的东西呢?

X=iNpiΓ(i+b)Γ(ib)Γ(c)+iNj<iqiΓ(i+b)Γ(jb)Γ(c)

在这种情况下piqi是实数。

现在我有一个总和,所以log属性没用。当然,我可以简单地用 log-gammas 替换所有的 gammas,但是,在这种情况下,我怎样才能找回我的原始结果呢?我可以做些什么来避免溢出吗?

1个回答

您可以通过适当地重写总和来避免溢出。说你有一笔钱

X=i=1nxi,
其中一些xi是正的并且大到足以导致溢出,但是logxi是合理的量级。如果你找到最伟大的logxMlogxi,那么你可以将总和重写为
logX=logielogxi=logxM+logielogxilogxM.
通过这样做,计算中只使用日志。在日志内的剩余总和中,我们有logxilogxM, 所以elogxilogxM1,这意味着剩余总和的值最多为n.

显然,如果xi's 有时可以是负数 - 在这种情况下,如果它们可以是负数并且与最终值相比相对较大,那么您可能会遇到灾难性的取消,尽管如果它们是负数且足够小则没有问题。