使用 `std::generate` 或 `std::fill` 填充 `arma::mat`

Using `std::generate` or `std::fill` to fill an `arma::mat`

我正在尝试围绕 gmm_fullgmm_diag 编写一个包装器,使它们成为 mvnorm_distribution。我需要这个特定的设置,因为我正在处理一个输入文件,并且希望一切都或多或少地与 std::*_distributions 相同。我有我的包装器,它可以正常工作,但我很难通过任何 std 算法填充 arma::mat。基本上,我有这样的东西:

arma::vec gen() {
    // gmm_full model initilization
    return model.generate();
}

void main() {
    arma::mat m(dim, N);
    std::generate(m.begin_col(0), m.end_col(N-1), gen);
}

到目前为止,我意识到 std::generatem.being_col() 没有像我预期的那样工作。我在想我会得到一个向量并可以填充它,或者这就是 std::generate 会做的,但显然事实并非如此。我在示例中看到我必须取消引用该列,但我无法在 std::generate 上执行此操作。我有 std::fillstd::transform 但到目前为止我没有成功。

一个解决方案是编写生成器 class 并逐个传递每个值,但这并不是我真正想要的。我想知道是否有人可以帮助我解决这个问题。我也知道 model.generate(N) 但我想包装分发并像其他 std::*_distribution 一样使用它,所以它不会解决我的问题,或者它可以但我没有知道怎么用了。

P.S。从技术上讲,这是我之前询问过的 的跟进。

我想我是通过使用 arma::mat::each_col 来管理的。这接受一个 lambda 函数并基本上遍历列。所以,它会是这样的:

    m.each_col([](vec& a) mutable {a = gen();});

不要忘记通过引用传递 a

警告:这可能比 arma::gmm_full::generate(N) or arma::mvnrnd 慢。因此,如果您只想生成大量样本,请先使用这些样本。

P.S。 mutable 不是必需的,除非您将分配传递给 lambda。