2

现在我正在使用 MonadRandom 库。我有一个计算:

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

我想多次执行它,并按顺序打印出结果。或者更确切地说,我想创建某种多重计算列表。

做一次,我会用

main = do
  result <- evalRandIO metroChain
  print result

或者

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

但是,我在打印任意 (n) 个metroChain结果时遇到了很多麻烦。

每个结果都应该使用最后一个结果末尾给出的 RandomGen ...... MonadRandom 应该是这样工作的,对吧?

我已经研究了replicateM,fmap和一些变形金刚(尽管我承认我似乎无法充分理解它们以掌握它们在我的问题中的应用)。

谁能帮我实现我正在寻找的功能?我觉得我错过了一些非常简单的东西。但我对 Haskell 很陌生。

4

2 回答 2

4

我将做出一个飞跃,并假设这metroStep是一个 MCMC Metropolis-Hastings 迭代。

您遇到的问题是您希望 MH 步骤是马尔可夫的,但是仅仅共享RandomGen状态(这正是replicateM n metroStep所做的)是不够的。这只会使每个步骤都能够基于独立的随机变量。比较一下,如果RandomGen不共享状态,那么不变性将保证每个状态metroStep都是相同的。

因此,您真正需要的是具有两种RandomGen状态的东西,以便提供用于生成自变量样本的伪随机数链固定状态,以便在每一步都可以拥有P(x_i | theta, x_(i-1))。为此,我们构建了一个转换器堆栈——我将使用该mtl库,random-fu因为几天前我刚刚使用这些库编写了一个 MCMC。

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

其中StateSpace是状态空间中的一个点,包括观察到的和未观察到的变量——它是似然函数右侧的每个参数。现在,replicateM n metroStep :: (MonadRandom m, MonadState StateSpace m) => m [StateSpace]是马尔可夫序列StateSpace点的列表。

然后我们像这样“运行”这个 monad 堆栈的具体版本

do steps <- (`runRVar` StdRandom) . (`evalStateT` ss0) $ (replicateM n metroStep)
   mapM_ print steps
于 2013-05-13T11:49:27.337 回答
3

replicateM是您在建立随机计算时想要的。(除非 tel 的猜测是正确的。)

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

然后你想mapM_帮助实际打印出结果。

这是做你想做的吗?你有什么想要我扩展的吗?

于 2013-05-13T11:49:39.670 回答