【问题标题】:Avoiding overflow in log(cosh(x))避免 log(cosh(x)) 溢出
【发布时间】:2020-01-07 03:50:40
【问题描述】:

我的模拟需要实现

np.log(np.cosh(x))

这对于大型x 会溢出,即。 e.我收到RuntimeWarning: overflow encountered in cosh 警告。原则上,随着对数减少所讨论的数字,在x 的某个范围内,cosh 应该溢出而log(cosh()) 不应该溢出。

在 NumPy 中是否有任何解决方案,例如在精神上类似于 np.log1p() 函数?

提供更多信息:我知道使用 SymPy 可能的解决方案可能是象征性的 https://github.com/sympy/sympy/issues/12671 但是模拟应该很快,并且符号计算 AFAIK 可能会显着减慢它。

【问题讨论】:

  • 您的dtype 设置为什么?
  • 它是 np.complex128(确实需要处理复数)。
  • 正要建议身份log(cosh(x)) = logaddexp(x, -x) - log(2),直到我看到关于复数的评论。

标签: python numpy numeric logarithm hyperbolic-function


【解决方案1】:

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 来实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多