2013-08-22 31 views
5

Czy log (a * b) jest zawsze szybszy w programie Matlab niż log (a) + log (b)?Czy log (a * b) jest zawsze szybszy w programie Matlab niż log (a) + log (b)?

Przetestowałem dla kilku wejść i wydaje się, że log (a * b) jest szybszy. Czy bardziej doświadczeni faceci mogą mi powiedzieć coś na ten temat? Może ostrzeżenia, że ​​to nie zawsze tak jest, czy coś w tym stylu, Czy powinienem być ostrożny? Tak więc w pierwszym przypadku mamy 1 log działania i 1 mnożenie, w drugim przypadku mamy dwie operacje logowania i jedno sumowanie.

Edit:

Aby dodać do mojego oryginalnego wpisu, bardziej ogólne pytanie brzmi:

jest log (a * b * ... * z) zawsze szybciej niż log (a) + log (b) + ... + log (z)?

Dzięki

+4

Wydawałoby się, że 'log' time >>' multiply time'> 'add time'.Ta obserwacja ma sens. – lurker

Odpowiedz

13

log(a*b) zawsze powinny być szybsze, ponieważ obliczanie logarytmu jest drogie. W log(a*b) robisz to tylko raz, w log(a)+log(b) robisz to dwa razy.

Obliczanie produktów i sum jest banalne w porównaniu do logarytmów, wykładników itp. Pod względem cykli procesorów zarówno sumy, jak i produkty są generalnie mniejsze niż 5, podczas gdy wykładniki i logarytmy mogą przejść od 50 do 200 cykli w przypadku niektórych architektur.

Czy log (a * b * ... * z) zawsze szybciej niż log (A) + log (b) + ... + log (z)

Tak. Zdecydowanie. W miarę możliwości unikaj obliczeń logarytmicznych.

Oto mały eksperyment:

a=rand(5000000,1); 

% log(a(1)*a(2)...) 
tic 
for ii=1:100 
    res=log(prod(a)); 
end 
toc 
% Elapsed time is 0.649393 seconds. 

% log(a(1))+log(a(2))+... 
tic 
for ii=1:100 
    res=sum(log(a)); 
end 
toc 
% Elapsed time is 6.894769 seconds. 

W pewnym momencie wskaźnik w czasie nasyci. Gdzie nasyca się zależy od architektury procesora, ale różnica będzie co najmniej rzędu wielkości.

+0

Różnica jest jeszcze bardziej drastyczna w przypadku złożonego dziennika, np. "A" jest wektorem złożonych wartości losowych. – horchler

+3

uważaj tutaj, pomnożenie wielu małych wartości w zakresie [0,1] szybko stanie się zerowe. Ten typ problemu często występuje w prawdziwym życiu podczas pracy z prawdopodobieństwami (http://en.wikipedia.org/wiki/Log_probability) ... Prędkość to nie wszystko, i powinieneś także martwić się stabilnością liczbową podczas pracy z liczbami zmiennoprzecinkowymi. – Amro

+0

Aby zilustrować, jak źle jest, w twoim przykładzie powyżej, tylko po około 700 elementach (z 5 milionów), że produkt stał się zero: 'sum (cumprod (a)> 0)' dał mi 729 – Amro

9

Uwaga: podczas obliczania log produkt jest szybszy, czasami może być nieprawidłowy ze względu na precyzję maszyny.

Jednym z problematycznych przypadków jest użycie wielu operandów całkowitych lub dużych liczb jako argumentów. W takim przypadku produkt a_1 * a_2 * ... a_n spowoduje przepełnienie, podczas gdy obliczenie sumy logarytmów nie będzie możliwe.

Innym problematycznym przypadkiem jest używanie małych liczb, tak, że ich produkt staje się zerowy z powodu precyzji maszyny (jak wspomniano w Amro).

+1

OK, w tym przypadku możemy może tworzyć produkty częściowe, mnożyć przed przepełnieniem, a następnie logować się do niego. Następnie rób to samo, zbieraj terminy na produkty, zanim przepełnisz dziennik. Zgodzić się? – user2381422

+1

Tak, to brzmi wykonalne. –

+2

+1 Dobra obserwacja na pytanie, na które odpowiedź została już wyrażona. – Werner

2

Chociaż zazwyczaj będzie to szybsze niż wykonanie log(a*b) zamiast log(a) + log(b), nie jest to ważne, jeśli trudno jest ocenić a*b. W takim przypadku może być tak, że szybsze jest użycie drugiej metody.

przykład:

a = 0; 
b = Inf; 
tic,for t = 1:1e6 log(a*b); end,toc 
tic,for t = 1:1e6 log(a)+log(b); end,toc 

Oczywiście to ocenić na NaN w obu przypadkach, ale drugi jest znacznie szybsza niż w pierwszym.

+0

0 * Inf jest obsługiwany z prędkością na nowoczesnych procesorach; nie ma nic trudnego do oceny. (W przeszłości niektórzy procesorzy spotykali się ze straganami wykonującymi operacje arytmetyczne z Infinities i NaN, ale to już nie jest prawdziwa troska) –

+0

Stawki TimStephenCanon pokazują, że jakoś nadal jest wolny. Być może powolną częścią jest ocena 'log (NaN)' zamiast tworzenia 'NaN' przez pomnożenie przez zero w nieskończoności. Oczywiście powolność jest względna, "normalny" przypadek jest tylko około 2 razy szybszy. –

+1

Z pewnością możliwe, że logi systemowe (nan) są wolniejsze niż log (0) i log (inf), ale byłoby to dziwactwo jednej implementacji biblioteki matematycznej, a nie powszechnie stosowane znalezisko. –

Powiązane problemy