2013-05-13 70 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