如何模拟 Rust 中的可组合随机过程?

jos*_*ule 6 random algorithm iterator coroutine rust

我正在编写一系列马尔可夫链蒙特卡罗 (MCMC)算法,通过将此处在 C++ 中实现的 MCMC 算法转换为 Rust 来用作程序归纳系统的推理方法。

MCMC 的粗略动态是我们有一些过程可以在对象空间周围随机移动并生成它发现的对象流。随机性是必不可少的。此外,此流永远不会终止(尽管您可以停止从流中获取对象)。更复杂的 MCMC 形式可以定义为这个基本过程的组合。

我的问题如何惯用地翻译这些算法?更具体地说,我如何从 rustacean 的角度考虑这个问题?为工作带来哪些正确的工具/技术?

这是我考虑过的:

  1. 直接翻译似乎很尴尬,因为 C++ 代码大量使用回调,鉴于我对 Rust 的了解有限,这感觉很尴尬。这似乎更符合我读过的其他 Rust 代码,只是让用户可以懒惰地使用他们认为合适的样本流。

  2. 然后我认为迭代器可能有意义,但是:

  • 我采样的对象是表示微型 DSL 的复杂数据结构。如果用户认为它是一个有用的样本,那么最好提供一个可以克隆的参考。我的理解是,鉴于 rust 的内存模型,这是迭代器的一个已知限制。
  • 这些算法都需要一个随机源(即&mut Rwhere R: Rng),并访问一个简单的控制结构来跟踪各种统计数据。将这些直接烘焙到任何结构实现中Iterator意味着我无法以共享控制结构或随机源的方式组合算法,对吗?
  1. 生成器/协程似乎解决了这些问题,但似乎是一个相对边缘/生锈的新领域。我开始怀疑我是否让事情变得比他们需要的更难。

  2. 我目前为每个算法提供了一个类似于以下函数的结构,其中H是假设,C是控制结构:

    impl<C, H> MCMCChain<C, H> {
        // ...
        pub fn next_sample<R: Rng>(&mut self, control: &mut C, rng: &mut R) -> Option<Self>
        // ...
    }
    
    Run Code Online (Sandbox Code Playgroud)

    理想情况下,next_sample会回来Option<&H>,但这就是我现在正在做的事情。