2013-05-13 68 views
2

現在我正在使用MonadRandom庫。我有一個計算:多次重複單次計算並打印出結果? (MonadRandom)

metroChain :: (RandomGen g) => Rand g Double 

我想多次執行它,並順序打印結果。或者說,我想創建一些多種計算列表。

做一次,我會用

main = do 
    result <- evalRandIO metroChain 
    print result 

main = evalRandIO metroChain >>= (\result -> print result) 

不過,我有很多的麻煩之中,能夠打印出的metroChain任意(N)量結果。

每個結果應該使用最後結果結尾給出的RandomGen ...這就是MonadRandom應該如何工作的,對嗎?

我已經看過replicateM,fmap,還有一點變成了變形金剛(雖然我承認我似乎無法理解他們足以把握他們的應用到我的問題)。

任何人都可以幫助我實現我正在尋找的功能嗎?我覺得我錯過了很簡單的事情。但我對Haskell來說很新。

+1

你試過'replicateM_'嗎? – Landei 2013-05-13 11:37:36

+1

n.b. '(\ result - > print result)'是'print'的複雜方式。 – dave4420 2013-05-13 11:51:44

回答

3

replicateM是你在建立隨機計算想要的東西。 (除非電話的猜測是正確的。)

foo :: Int -> IO() 
foo n = do 
    results <- evalRandIO (replicateM n metroStep) 
    mapM_ print results 

那麼你一定要mapM_在實際打印出來的結果,以幫助。

這是做你想做的嗎?有什麼你想讓我擴展的嗎?

+0

這正是我正在尋找的:) – 2013-05-13 15:51:43

4

我打算做一個飛躍,並假設metroStep是MCMC Metropolis-Hastings迭代。

您遇到的問題是,您希望MH步驟是馬爾可夫,但僅僅共享RandomGen狀態,這正是replicateM n metroStep所做的不足。這隻能使每個步驟都能夠基於獨立的隨機變量。爲了比較,如果RandomGen狀態不共享,則不變性將保證每個metroStep是相同的。

所以你真正需要的是什麼,爲了生成自變量樣本固定狀態,這樣在每一個步驟,你可以有P(x_i | theta, x_(i-1))提供psuedorandom數的鏈既有RandomGen狀態。我們建立一個變壓器堆棧來做到這一點 - 我將使用mtl庫和random-fu,因爲我幾天前剛剛使用這些庫編寫了一個MCMC。

metroStep :: (MonadRandom m, MonadState StateSpace m) => m StateSpace 

其中StateSpace處於狀態空間既包括觀察點不可觀測的變量,它是在你的似然函數的右側,每個參數。現在,replicateM n metroStep :: (MonadRandom m, MonadState StateSpace m) => m [StateSpace]是馬爾可夫序列StateSpace分的列表。

然後我們「跑」這個單子堆棧的具體版本是這樣

do steps <- (`runRVar` StdRandom) . (`evalStateT` ss0) $ (replicateM n metroStep) 
    mapM_ print steps 
+0

'metroStep'實際上命名不正確,它是大都會算法的n次迭代。在我的實際代碼中,它是'metroChain n'。我已經有了一種從多個獨立步驟製作metroChain的方法? – 2013-05-13 15:45:07

+0

我應該使用mtl/statespace切換到完成狀態嗎? 這是我目前的「完整」代碼 - https://gist.github.com/mstk/5569453 我應該重構一下嗎? – 2013-05-13 16:08:13

+0

您的metroChain基本上是將replicateM應用於狀態monad,放棄結果。您可以在它上面使用print,mapM和replicateM的組合來獲得您的結果。 – 2013-05-13 19:18:05