避免log(cosh(x))中的溢出问题

8
我的模拟需要实现
np.log(np.cosh(x))

这会在大的x值时溢出,即我会收到RuntimeWarning: overflow encountered in cosh的警告。原则上,随着对数减少问题中的数字,在某个x范围内,cosh应该溢出,而log(cosh())则不应该。
在NumPy中是否有解决方案,例如类似于np.log1p()函数的精神?
提供更多信息:我知道可能的解决方案可能是使用SymPy进行符号计算,但据我所知,符号计算可能会显着减慢模拟速度。https://github.com/sympy/sympy/issues/12671

你的 dtype 设置为什么了? - FlyingTeller
它是np.complex128(确实需要处理复数)。 - WojciechR
1
刚要建议使用 log(cosh(x)) = logaddexp(x, -x) - log(2) 这个等式,直到看到关于复数的评论。 - myrtlecat
1个回答

12
下面的log(cosh(x))实现应该是数值稳定的:
import numpy as np

def logcosh(x):
    # s always has real part >= 0
    s = np.sign(x) * x
    p = np.exp(-2 * s)
    return s + np.log1p(p) - np.log(2)

解释:

对于实数,您可以使用以下恒等式:

log(cosh(x)) = logaddexp(x, -x) - log(2)
             = abs(x) + log1p(exp(-2 * abs(x))) - log(2)

这是一种数值稳定的方法,因为作为exp的参数始终为非正数。对于复数,我们要求exp的参数具有非正实部,通过在real(x) > 0时使用-x,否则使用x来实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接