微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何计算数字数组的对数阶乘

如何解决如何计算数字数组的对数阶乘

要计算的数量log(k!),其中 k 可以是 4000 甚至更高,但当然日志会补偿。我尝试计算 sum(log(k)),这是相同的。

所以,我得到了一个包含整数的大数组,我想有效地计算 sum(log(k))。这是我的尝试:

integers = np.asarray([435,535,242,])

score = np.sum(np.log(np.arange(1,integers+1)))

这会起作用,除了 np.arange 会为每个整数生成一个不同大小的数组,所以当我运行它时,它会给我一个错误(应该如此)。

这个问题可以用 for 循环轻松解决,如下所示:

scores = []
for i in range(integers.shape[0]):
    score = np.sum(np.log(np.arange(1,integer[i]+1)))
    scores.append(score)

但这太慢了。我的实际 integers 有数百万个要计算的值。

是否有一个有效的实现,基本上不需要 for 循环?我正在考虑 lambda 函数或类似的东西,但我不确定如何应用它。任何帮助表示赞赏!

解决方法

math.lgamma 怎么样? Gamma 函数是阶乘,lgamma 是 gamma 的对数。

您不需要计算阶乘然后记录。

SciPy 中也有 gammaln

代码,Python 3.9 x64 Win 10

import numpy as np
from scipy.special import gammaln

startf = 1 # start of factorial sequence
stopf  = 400 # end of of factorial sequence

q = gammaln(range(startf+1,stopf+1)) # n! = G(n+1)
print(q)

我觉得很合理

,

您可以使用以下方法进行矢量化:

mi = integers.max()
ls = np.log(np.arange(2,mi + 1))

目前有两个优化:您只需要最大范围,因为其他数字都包含在内,而您不需要 log(1)

现在计算累计总和:

cs = np.cumsum(ls)

可以直接索引所需元素:

result = cs[integers - 2]

如果您需要多次执行此操作,并且您知道上限,那么一旦您预先计算 math.lgmamma 到上限。

如果这是一次性电话,这是强制性的单行电话:

scipy.special.gammaln

如果内存是一个问题,您可以就地执行大部分操作(我认为这也使它们更快):

cs

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。