Я занимаюсь математикой с очень большими числами (я использую Python, но этот вопрос не специфичен для Python). Для одного значения у меня есть формула, которая дает мне f(t) = Pr(X < t)
. Я хочу использовать эту формулу, чтобы получить Pr(X >= t) = 1 - f(t)
. Поскольку f(t)
возвращает значения, очень близкие к нулю, я использовал логарифмическое преобразование и сохранял log( f(t) )
вместо f(t)
. Мой log( f(t) )
порядка -1e5 или около того.
Для умножения это работает очень хорошо. log( f(t) * g ) = log( f(t) ) + log(g)
.
Но очень сложно вычислить log( 1 - f(t) )
, используя только log( f(t) )
; Я мог бы, конечно, временно возвести в степень сохраняемое значение и вычислить log( 1 - exp( log( f(t) ) )
, но это вернет log( 1 - 0.0 ) = 0.0
, потому что log( f(t) )
так близко к нулю.
Вы можете спросить: «Какое вам дело? Если оно близко к нулю, то 1 минус очень близко к 1». Что ж, это хорошее замечание, которое вы сделали. Ты умница.
Проблема в том, что я хочу использовать это для ранжирования значений, поэтому мне действительно важно, будет ли одно из них log(0.999)
, а другое — log(0.9999)
. Вы также можете спросить: «Почему бы вам просто не ранжировать log( f(t) )
, а затем изменить порядок, чтобы получить ранжирование для log( 1 - f(t) )
». Опять же, я не могу не отметить, насколько хороши ваши вопросы. Было действительно приятно поговорить с вами.
Но вот проблема: я не просто хочу ранжироваться на 1 - f(t)
; На самом деле я хочу ранжироваться на основе Pr(X >= t) * g(t) = (1 - f(t)) g(t)
. После сбора логов получаю log( 1 - f(t) ) + log( g(t) )
; ранжирование, основанное только на f(t)
, не даст правильного ответа.
В прошлом я написал небольшую функцию Python для вычисления log(a + b)
из log(a)
и log(b)
:
def log_add(logA,logB):
if logA == log(0):
return logB
if logA<logB:
return log_add(logB,logA)
return log( 1 + math.exp(logB-logA) ) + logA
Это помогает сначала нормализовать их, чтобы они были близко друг к другу, а затем возводить в степень, когда они близко друг к другу.
К сожалению, я не смог использовать тот же трюк для моего вычитания, потому что нет коэффициента нормализации, который сближал бы log(1)
и log( f(t) )
, потому что они так далеко друг от друга.
Кто-нибудь знает, как это решить? Это похоже на классическую проблему; Я действительно ожидаю/надеюсь/молюсь, что есть умная функция, работающая на уровне битов, которая может дать мне log(1-x)
из log(x)
. Кроме того, если вы знаете, как это работает, мне бы очень хотелось узнать.
Ваше здоровье! Оливер