Większość bibliotek matematycznych ma wiele wersji funkcji logarytmicznych. Przez większość czasu zakładamy, że są idealne, ale w rzeczywistości całkiem sporo z nich oferuje określoną liczbę cyfr precyzji.
W przypadku niektórych funkcji istnieją stabilniejsze numerycznie warianty. Na przykład Fortran, R, Java i C mają Math.log1p
, zarówno do obliczeń log(1.0+x)
(która oferuje wyższą precyzję dla małych wartości x), jak i odpowiednik expm1
. Tutaj problemy numeryczne wynikają z utraty precyzji - jeśli x
jest naprawdę mały, 1.0 + x
traci cyfry, aby zachować 1 na początku.
Widziałem takie funkcje dla większej precyzji w wielu sytuacjach. Wydaje się to dość powszechne, gdy implementujesz funkcje dystrybucji (Gamma, Beta, Poisson itp.) Z wysoką precyzją numeryczną. Na przykład funkcja Gamma wydaje się być używana przez większość czasu jako logGamma
. Ogólnie rzecz biorąc, przejście do „logspace” może znacznie poprawić precyzję, więc R wydaje się mieć flagę „logspace” na większości funkcji.
Kolejny przykład, w R, istnieje log1mexp
dla log(1 - exp(p))
:
http://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf
Bawiłem się metodami entropii i teorii. Istnieje bardzo powszechny termin
p * -log(p)
gdzie zwykle chcielibyśmy, aby podstawą logarytmu była 2, a nie e; ale równie często jest to tylko czynnik liniowy i równie dobrze możesz użyć logarytmu naturalnego (więc nie ma to dla mnie kluczowego znaczenia). W każdym razie, czy wiesz, czy istnieje szybszy / bardziej bezpośredni / bardziej precyzyjny sposób obliczenia tego terminu? Mam to wszędzie, więc naprawdę może się opłacić, aby uczynić to nieco bardziej precyzyjnym i szybkim (oszczędzaj mi zwykłych rzeczy przedwczesnej optymalizacji, dzięki).
Nie widzę żadnego oczywistego powodu, który spowodowałby utratę precyzji. Dlatego najbardziej interesuje mnie, czy istnieje jakiś fajny sposób na przyspieszenie tego obliczenia. Może to nawet oszczędza mi traktowania p=0
narożnej skrzynki (która jest rozsądna 0
, chociaż log(0)
nie istnieje) lub daje mi bazę 2 za darmo (chociaż pojedyncze zwielokrotnienie ze stałą oczywiście nie jest zabójcze). Dzięki.
źródło
log2
funkcję, która w zależności od systemu operacyjnego może być prostym rozwiązaniemlog/log(2)
lub wykorzystać fakt, że C99 dodałlog2
funkcję.Odpowiedzi:
źródło