Чтобы сформулировать вопрос, в информатике часто мы хотим вычислить произведение нескольких вероятностей:
P(A,B,C) = P(A) * P(B) * P(C)
Самый простой подход - просто умножить эти числа, и это то, что я собирался сделать. Однако мой начальник сказал, что лучше добавить журнал вероятностей:
log(P(A,B,C)) = log(P(A)) + log(P(B)) + log(P(C))
Это дает логарифмическую вероятность, но мы можем получить вероятность впоследствии при необходимости:
P(A,B,C) = e^log(P(A,B,C))
Добавление журнала считается лучшим по двум причинам:
- Это предотвращает «недопущение», при котором произведение вероятностей настолько мало, что оно округляется до нуля. Это часто может быть риском, так как вероятности часто очень малы.
- Это быстрее, потому что многие компьютерные архитектуры могут выполнять сложение быстрее, чем умножение.
Мой вопрос о втором пункте. Вот как я это описал, но это не учитывает дополнительную стоимость получения журнала! Мы должны сравнивать «стоимость лога + стоимость сложения» с «стоимостью умножения». Это все еще меньше после учета этого?
Кроме того, страница Википедии ( Вероятность журнала ) вводит в заблуждение в этом отношении, заявляя: «Преобразование в форму журнала дорого, но происходит только один раз». Я не понимаю этого, потому что я думаю, что вы должны были бы взять журнал каждого термина независимо, прежде чем добавлять. Чего мне не хватает?
Наконец, обоснование того, что «компьютеры выполняют сложение быстрее, чем умножение», является довольно расплывчатым. Это специфично для набора команд x86 или это более фундаментальная черта процессорных архитектур?
Ответы:
Если вы просто хотите вычислить один раз, то вы правы. Вам нужно будет вычислить n логарифмов ип( А1) … P( АN) N сложений, тогда как простой метод требует n - 1 умножений.n - 1 n - 1
Тем не менее, очень часто вы хотите отвечать на запросы в форме:
В этом случае вы можете предварительно обработать ваши данные для вычисления всегожурналп( Ая) только один раз, и ответить на каждый запрос, выполнив дополнения.| я|
Это более широкий вопрос. Вообще (наверное?) Сложнее вычислить умножение, чем сложение. Вычисление является линейным по размеру a и b (используя тривиальный алгоритм), в то время как в настоящее время мы не знаем, как вычислить a × b с той же временной сложностью (посмотрите лучшие алгоритмы здесьa+b a b a×b ).
Конечно, нет однозначного ответа: например, если вы имеете дело только с целыми числами и умножаете на степени , вам лучше сравнить сдвиг с операциями сложения.2
Тем не менее, это разумное утверждение для всех распространенных компьютерных архитектур: умножение на числа с плавающей запятой будет медленнее, чем сложение.
источник
Кстати, эта идея похожа на модульное умножение Монтгомери, где умножения выполняются в форме Монтгомери, которая является более быстрой, чем обычное умножение, а затем сокращение.
источник