避免日志溢出(cosh(x))
Avoiding overflow in log(cosh(x))
我的模拟需要实现
np.log(np.cosh(x))
这会溢出大 x
,i。 e.我收到 RuntimeWarning: overflow encountered in cosh
警告。原则上,随着对数减少所讨论的数字,在 x
的某些范围内,cosh
应该溢出,而 log(cosh())
不应该溢出。
在 NumPy 中是否有任何解决方案,例如在精神上类似于 np.log1p()
函数?
提供更多信息:我知道一个可能的解决方案可能是使用 SymPy 的象征性的
https://github.com/sympy/sympy/issues/12671
但是模拟应该很快,而符号计算 AFAIK 可能会显着降低速度。
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
来实现这一点=17=] 否则。
我的模拟需要实现
np.log(np.cosh(x))
这会溢出大 x
,i。 e.我收到 RuntimeWarning: overflow encountered in cosh
警告。原则上,随着对数减少所讨论的数字,在 x
的某些范围内,cosh
应该溢出,而 log(cosh())
不应该溢出。
在 NumPy 中是否有任何解决方案,例如在精神上类似于 np.log1p()
函数?
提供更多信息:我知道一个可能的解决方案可能是使用 SymPy 的象征性的 https://github.com/sympy/sympy/issues/12671 但是模拟应该很快,而符号计算 AFAIK 可能会显着降低速度。
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
来实现这一点=17=] 否则。