Я использую добавление в уравнении пространства журналов, описанное в статье Wikipedia log probability, но я получаю недостаточное значение при вычислении exp очень больших отрицательных логарифмов. В результате моя программа выйдет из строя.Предотвращение переполнения при добавлении двух логарифмов
Примеры ввода: a = -2
и b = -1033.4391885529124
.
Мой код, реализованный прямо из статьи Википедии, выглядит следующим образом:
double log_sum(double a, double b)
{
double min_ab = std::min(a, b);
a = std::max(a, b);
b = min_ab;
if (isinf(a) && isinf(b)) {
return -std::numeric_limits<double>::infinity();
} else if (isinf(a)) {
return b;
} else if (isinf(b)) {
return a;
} else {
return a + log2(1 + exp2(b - a));
}
}
Я придумал следующие идеи, но не может решить, что лучше:
- Перед оценкой проверьте наличие вне диапазона.
- Отключить (как-то) исключение и вымыть или закрепить результат после оценки
- Реализация пользовательских функций журнала и экспозамера, которые не генерируют исключений и автоматически очищают или зажимают результаты.
- Некоторые другие способы?
Кроме того, мне было бы интересно узнать, какой эффект имеет выбор базы логарифмов при вычислении. Я выбрал базовую пару, потому что считал, что другие базы журналов будут вычисляться от log_n(x) = log_2(x)/log_2(n)
и будут страдать от потери точности из-за деления. Это верно?
Вам нужно иметь> b? Я не вижу этого в вашем коде. Также на странице wikipedia предлагается использовать log1p, который у вас нет (хотя я не знаю эквивалента в базе 2). –
Мне было рекомендовано внести это изменение. См. Обновленный код. Я получаю неправильные результаты при использовании log1p и expm1. –
Невозможно воспроизвести. Как сбой вашей программы? exp: 'Если ошибка диапазона возникает из-за недостаточного потока, возвращается правильный результат (после округления). – 4386427