2011-02-04 39 views
7

在C++中工作,我想找到一些量的總和,然後取總和的日誌:有效地總結日誌數量

log(a_1 + a_2 + a_3 + ... + a_n) 

不過,我沒有量自己,我只有他們的log'd值:

l_1 = log(a_1), l_2 = log(a_2), ... , l_n = log(a_n) 

有沒有任何有效的方法來獲得日誌的總和的a_i?我想避免

log(s) = log(exp(l_1) + exp(l_2) + ... + exp(l_n)) 

如果可能的話--exp因爲多次計算而成爲瓶頸。

+7

嘿,這是[數學問題](http://jblev​​ins.org/notes/log-sum- exp)僞裝! – 2011-02-04 22:49:37

+2

太糟糕了,你不是在尋找日誌(a_1 * ... * a_n) - 你可以總結你的日誌值! – 2011-02-04 22:59:37

回答

3

n有多大?

這個數量被稱爲log-sum-exp,Lieven Vandenberghe在他的book的第72頁上談到它。他還有一個使用這個操作的optimization package,並且從簡單的角度看,他似乎沒有在那裏做任何特別的事情,只是求冪而已。也許指數化並不是一個嚴重的瓶頸,當n足夠小以使載體適應記憶時。

該操作經常出現在建模中,而且存在大量術語的瓶頸。 n = 2^100的大小是常見的,其中術語被隱含地表示。在這種情況下,依靠log-sum-exp的凸性來逼近這個數量有各種技巧。最簡單的技巧 - 近似日誌(s)爲max(l1,l2,...,ln)

3

我不知道有什麼辦法,因爲,在一般情況下,沒有辦法

ËX + E Ÿ

使用加法,只有一個計算指數,這相當於你問的東西。


正如上面弗雷德裏克·哈米迪的評論中提到,即使你做了總結的指數,你有另外一個問題擔心:溢出。該link he gave給出了一個不錯的解決方案(以下從該鏈接複製Fortran代碼)

function log_sum_exp(v) result(e) 
    real, dimension(:), intent(in) :: v ! Input vector 
    real       :: e ! Result is log(sum(exp(v))) 
    real       :: c ! Shift constant 

    ! Choose c to be the element of v that is largest in absolute value. 
    if (maxval(abs(v)) > maxval(v)) then 
    c = minval(v) 
    else 
    c = maxval(v) 
    end if 

    e = log(sum(exp(v-c))) + c 
end function log_sum_exp 
1

您可以使用下面的身份:

log(a + b) = log(a) + log(1 + (b/a)) 
1

這不是很優雅,但你可以嘗試以下。

  • 獲得(由log 2除)從log a_ilg a_i
  • lg a_i = k + q其中k是整數和q是真實的,0 >= q >= 1
  • 獲取a_i用2 ķpow(2,q)(使用比特移位2 ķ = 1 << k)。
  • 您可以與[0,1]

所以整個想法是利用一個快速功率爲2的功能的精確度有限,預計算表加快pow(2,q)。希望能幫助到你!

1

如果S_K:= sum(a_1 + ... + a_k)然後 S_ {K + 1} == s_k + f(l_{k+1} - s_k),其中

f(x) := log(1+exp(x)) 

此功能f大概可以用泰勒級數或具有比得上exp速度類似地計算,並且甚至可能內聯。

這隻能保存兩個數學函數,但它可能是一個有用的起點。