Numba 支持大整数?
Numba support for big integers?
我有一个包含前 30 个整数阶乘的阶乘查找 table。此 table 用于使用 numba.njit
编译的函数中。问题是,大于 20!,该数字大于 64 位有符号整数 (9,223,372,036,854,775,807), which causes numba to raise a TypingError。如果 table 减少为仅包含前 20 个整数阶乘,则函数运行正常。
有没有办法在 numba 中解决这个问题?也许通过在使用查找 table 的 jit 编译函数中声明更大的整数类型?
可能有一些方法可以在 Numba 中处理大整数,但我不知道它是一种方法。
但是,由于我们知道您正在尝试在 Numba 中手动编写 Beta distribution 的评估,因此我有一些其他建议。
首先,我们必须注意我们的语言,以免混淆 Beta distribution and the Beta function。
我真正建议的是将所有计算移至对数刻度。也就是说,不是计算 Beta 分布的 pdf,而是计算 Beta 分布的 pdf 的对数。
这个技巧常用于统计计算,因为 pdf 的对数在数值上比 pdf 更稳定。例如,Stan project 专门用于计算日志 posterior 密度。
从你的post历史我也知道你对 MCMC 很感兴趣;使用日志 pdf 执行 MCMC 也是常见的做法。在 MCMC 的情况下,不是让 posterior 与先验概率成比例,在对数尺度上你会有 log-posterior正比于 log-prior plus log-likelihood.
我建议您使用对数分布,因为这可以让您避免必须为大 n 计算 $\Gamma(n)$,这很容易出现整数溢出。相反,您计算 $\log(\Gamma(n))$。但是你不需要计算 $\Gamma(n)$ 来计算 $\log(\Gamma(n))$ 吗?实际上,不。您可以查看 scipy.special
函数 gammaln
,它完全避免了计算 $\Gamma(n)$。一种前进的方式是查看 scipy.special.gammaln
中的源代码,并据此制作您自己的 numba 实现。
在您的评论中,您还提到使用 Spouge's Approximation to approximate the Gamma function. I've not used Spouge's approximation before, but I have had success with Stirling's approximation. If you want to use one of these approximations, working on the log scale you would now take the log of the approximation. You'll want to use the rules of logs 重写这些近似值。
考虑到以上所有因素,我建议将计算从 pdf 移动到 pdf 的日志。要计算 Beta 分布 的日志 pdf,我会使用 this approximation of the Beta function。使用日志规则重写此近似值和 Beta pdf。然后你可以实现这是 Numba 而不必担心整数溢出。
编辑
抱歉,我不确定如何在堆栈溢出时格式化数学。
我有一个包含前 30 个整数阶乘的阶乘查找 table。此 table 用于使用 numba.njit
编译的函数中。问题是,大于 20!,该数字大于 64 位有符号整数 (9,223,372,036,854,775,807), which causes numba to raise a TypingError。如果 table 减少为仅包含前 20 个整数阶乘,则函数运行正常。
有没有办法在 numba 中解决这个问题?也许通过在使用查找 table 的 jit 编译函数中声明更大的整数类型?
可能有一些方法可以在 Numba 中处理大整数,但我不知道它是一种方法。
但是,由于我们知道您正在尝试在 Numba 中手动编写 Beta distribution 的评估,因此我有一些其他建议。
首先,我们必须注意我们的语言,以免混淆 Beta distribution and the Beta function。
我真正建议的是将所有计算移至对数刻度。也就是说,不是计算 Beta 分布的 pdf,而是计算 Beta 分布的 pdf 的对数。
这个技巧常用于统计计算,因为 pdf 的对数在数值上比 pdf 更稳定。例如,Stan project 专门用于计算日志 posterior 密度。
从你的post历史我也知道你对 MCMC 很感兴趣;使用日志 pdf 执行 MCMC 也是常见的做法。在 MCMC 的情况下,不是让 posterior 与先验概率成比例,在对数尺度上你会有 log-posterior正比于 log-prior plus log-likelihood.
我建议您使用对数分布,因为这可以让您避免必须为大 n 计算 $\Gamma(n)$,这很容易出现整数溢出。相反,您计算 $\log(\Gamma(n))$。但是你不需要计算 $\Gamma(n)$ 来计算 $\log(\Gamma(n))$ 吗?实际上,不。您可以查看 scipy.special
函数 gammaln
,它完全避免了计算 $\Gamma(n)$。一种前进的方式是查看 scipy.special.gammaln
中的源代码,并据此制作您自己的 numba 实现。
在您的评论中,您还提到使用 Spouge's Approximation to approximate the Gamma function. I've not used Spouge's approximation before, but I have had success with Stirling's approximation. If you want to use one of these approximations, working on the log scale you would now take the log of the approximation. You'll want to use the rules of logs 重写这些近似值。
考虑到以上所有因素,我建议将计算从 pdf 移动到 pdf 的日志。要计算 Beta 分布 的日志 pdf,我会使用 this approximation of the Beta function。使用日志规则重写此近似值和 Beta pdf。然后你可以实现这是 Numba 而不必担心整数溢出。
编辑
抱歉,我不确定如何在堆栈溢出时格式化数学。