Как избежать переполнения журнала (cosh(x))

Мое моделирование необходимо реализовать

np.log(np.cosh(x))

Это переполняет большие x, т.е. я получаю RuntimeWarning: overflow encountered in coshпредупреждение. В принципе, поскольку логарифм уменьшает рассматриваемое число, в некотором диапазонеx, cosh должен переполняться пока log(cosh()) не следует.

Есть ли какое-либо решение для этого в NumPy, например, похожее по духу на np.log1p() функция?

Чтобы предоставить дополнительную информацию: я знаю, что возможное решение может быть символическим с использованием SymPyhttps://github.com/sympy/sympy/issues/12671, однако моделирование должно быть быстрым, а символьные вычисления AFAIK могут значительно замедлить его.

2 ответа

Решение

Следующая реализация 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имеет неположительную действительную часть, которую мы достигаем, используя-x когда real(x) > 0 а также x иначе.

Cosh (x) -> журнал (1/2 (e ^ (- x) + e ^ x))

e ^ x -> e ^ (a + ib) -> e ^ a cos (b) + ie ^ a sin (b)

Даже если b очень велико, легко вычислить cos (x), sin (x), поскольку они периодические.

Теперь, чтобы вычислить e ^ a cos (b)

х = cosb(б)

х * е ^ а -> е ^ (а +ln(х))

Также обратитесь к символическим вычислениям в Wolfram Alpha:

https://www.wolframalpha.com/input/?i=log%28cosh%28x%29%29

https://www.wolframalpha.com/input/?i=e%5E%28a%2Bix%29

Другие вопросы по тегам