Как избежать переполнения журнала (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: