【问题标题】:Using `std::generate` or `std::fill` to fill an `arma::mat`使用 `std::generate` 或 `std::fill` 填充 `arma::mat`
【发布时间】:2019-06-13 09:16:37
【问题描述】:

我正在尝试围绕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,但到目前为止我还没有成功。

一种解决方案是编写一个生成器类并一个一个地传递每个值,但这并不是我真正想要的。我想知道是否有人可以帮助我解决这个问题。我也知道model.generate(N),但我想将分发包打包并像其他std::*_distributions 一样使用它,所以它不能解决我的问题,或者它确实解决了我不知道如何使用它。

附:从技术上讲,这是我之前询问过的 this question 的后续行动。

【问题讨论】:

  • 为什么不使用 arma::mat::imbue 接受 lambda,或使用 arma::mat::fill 表示常量值?
  • imbue 还通过它的元素 col-by-col 遍历 arma::mat,而不是通过它的列。这里的关键区别在于mvnorm_dist 返回一个向量而算法的其余部分返回一个双精度值,并且大多数迭代器是逐个元素遍历的。 arma::mat::begin_col 给出了一个指向列的指针,但我不知道如何在 Lamba 中使用它。我认为这是我的主要问题。

标签: c++ random c++17 std


【解决方案1】:

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

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

不要忘记通过引用传递a

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

附: mutable 不是必需的,除非您将分发传递给 lambda。

【讨论】:

    猜你喜欢
    • 2013-07-15
    • 1970-01-01
    • 2017-12-23
    • 2016-04-01
    • 1970-01-01
    • 2017-07-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    相关资源
    最近更新 更多