Python中求和的数值函数

2024-04-18 23:09:07 发布

您现在位置:Python中文网/ 问答频道 /正文

给定log(a)和{},我想计算log(a+b)(以数值稳定的方式)。在

我为此写了一个小函数:

def log_add(logA,logB):
    if logA == log(0):
        return logB
    if logA<logB:
        return log_add(logB,logA)
    return log( 1 + math.exp(logB-logA) ) + logA

我编写了一个程序,其中这是迄今为止最耗时的一段代码。显然,我可以尝试优化它(例如,消除递归调用)。在

你知道一个标准的math或{}函数,用于从log(a)和{}计算{}?在

如果不是,你知道一个简单的方法来为这个函数制作一个C++钩子吗?它不是一个复杂的函数(它使用float),正如我所说,它占用了我运行时的大部分时间。在

提前感谢,数值方法忍者!在


Tags: 方法函数代码程序logaddreturnif
2条回答
def log_add(logA, logB): 
    return math.log(math.exp(logA) + math.exp(logB))

太慢了?还是不准确?在

{cd1>最好现在就用。在

为什么要与log(0)进行比较?这等于-numpy.inf,在本例中,您将得到{},它将自身简化为logB。此呼叫总是会发出一条非常慢的警告消息。在

我可以想出这一套。不过,你需要真正的衡量,看看这是否真的更快。它只使用一个“complex”计算函数,而不是您使用的两个函数,并且没有递归,if仍然存在,但隐藏在fabs/maximum中。在

def log_add(logA,logB):
    return numpy.logaddexp(0,-numpy.fabs(logB-logA)) + numpy.maximum(logA,logB)

编辑:

我做了一个快速timeit(),结果如下:

  1. 你的原始版本花了120秒
  2. 我的版本花了大约30秒
  3. 我从你的版本中删除了与日志(0)的比较,结果降到了20秒
  4. 我编辑了我的代码以保留logaddexp,但也使用了递归if,并且它降到了18

更新代码后,您还可以使用内联更新公式切换递归调用,但这在我的计时测试中几乎没有什么不同:

^{pr2}$

编辑2:

正如pv在评论中指出的,实际上您可以只做numpy.logaddexp(logA, logB),这归结为计算log(exp(logA)+exp(logB)),这当然等于log(A+B)。我给它计时(在上面的同一台机器上),它进一步下降到大约10秒,所以我们降到了大约1/12,不错;)。在

相关问题 更多 >