Большинство математических библиотек имеют несколько версий логарифмических функций. Большую часть времени мы предполагаем, что они идеальны, но на самом деле многие из них просто предлагают определенное количество цифр точности.
Для некоторых функций существуют численно более стабильные варианты. Например, Fortran, R, Java и C оба имеют Math.log1p
для вычислений log(1.0+x)
(что обеспечивает более высокую точность при малых значениях x) и аналог expm1
. Здесь числовые проблемы возникают из-за потери точности - если x
она действительно мала, 1.0 + x
теряет цифры, чтобы сохранить 1 в начале.
Я видел такие функции для повышения точности в ряде ситуаций. Это кажется довольно распространенным явлением, когда вы реализуете функции распределения (гамма, бета, пуассон и т. Д.) С высокой числовой точностью. Например, гамма-функция, кажется, большую часть времени используется как logGamma
. В общем, переход к «logspace» может значительно повысить точность, поэтому R, похоже, имеет флаг «logspace» для большинства функций.
Другой пример в R существует log1mexp
для log(1 - exp(p))
:
http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf
Я играл с энтропией и теоретико-информационными мерами. Очень распространенный термин
p * -log(p)
где обычно требуется, чтобы основание логарифма было 2, а не е; но так же часто это только линейный фактор, и вы также можете использовать натуральный логарифм (так что для меня это не имеет ключевого значения). В любом случае, знаете ли вы, существует ли более быстрый / более прямой / более точный способ вычисления этого термина? У меня есть все это повсеместно, так что это может действительно окупиться, чтобы сделать его немного более точным и быстрым (спасите меня от обычного "преждевременной оптимизации", спасибо).
Я не вижу очевидной причины, которая могла бы привести к потере точности. Так что мне больше всего интересно, есть ли какая-нибудь хорошая хитрость, чтобы ускорить это вычисление. Это, возможно, даже спасает меня от лечения p=0
углового случая (что разумно 0
, хотя log(0)
и не существует) или дает мне базу 2 бесплатно (хотя одно умножение с константой, очевидно, не слишком дорого). Спасибо.
log2
функцией, которая в зависимости от вашей ОС может быть простой оболочкой log/log(2)
или использовать тот факт, что C99 добавил log2
функцию.