【问题标题】:Implementing the Metropolis Algorithm in Haskell在 Haskell 中实现 Metropolis 算法
【发布时间】:2014-04-05 18:35:49
【问题描述】:

我正在尝试基于 Haskell 中的 Metropolis 算法编写一个 MCMC 程序,但我在从概率分布(生成伪随机数)采样和构建程序时遇到了问题。现在我很高兴使用带有硬编码种子的生成器,而不是处理处理 IO 的复杂性。

看来我应该使用状态单子来跟踪随机生成器的状态,之前的马尔可夫链状态,卡方值和算法每一步之间的接受计数,然后最后收集所有马尔可夫链状态和最后一次接受计数。这是最好的/惯用的方法吗?如果是这样,程序的布局应该是什么(即提案功能和大都会阶梯功能的类型签名等)。

我见过一些处理随机数的示例程序,其中特定长度的随机数列表是从某种概率单子生成的,然后通过一些简单的函数进行线程化以执行计算。如果可能的话,我真的很想避免这种由内而外的程序形式。

编辑:暂时删除 WIP 代码。

【问题讨论】:

    标签: haskell random mcmc


    【解决方案1】:

    这里是一些关于编写惯用 Haskell 的反馈。

    • 除非你正在编写一元代码,否则在纯函数中使用do (即constructMuTablemetropolis)是非常不习惯的 Haskell。

      代替

      foo = do
          let x = ...
              y = ...
              z = ...
          bar x y z
      

      随便写

      foo =
          let x = ...
              y = ...
              z = ...
          in bar x y z
      

      或使用where 代替let ... in ...

    • eta 减少。在某些地方(zVecmuVecsigmaVecmain)你写了(\x -> f x)。这仅相当于f、模_|_seq 等。

    • 使用Data.Vector.Unboxed。你有很多V.Vector Double,它们存储盒装的Doubles,可能效率低下。对于像 Double 这样的原始类型,使用未装箱的向量(可能)使用更少的内存更快地编写代码。

    • 尽可能避免使用(!!) 索引列表。使用Data.Vector 代替V.!O(1)(!!)O(n)

    • 您似乎可以在这里使用State monad 来清理您的代码。然而,以目前的命令形式,我很难看到这种转变。

    也许您可以尝试应用我给出的一些建议并简化一些大型、密集的函数,然后对您的算法的更高级别的反馈将变得更加明显。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多