遍历arma :: mat并检索元素位置

问题描述

我正在尝试逐个设置arma::mat元素的值,每个元素的值取决于每个元素的多索引(行,列)。 是否可以在迭代过程中检索元素的当前位置?

基本上,我希望能够执行like in the sparse matrix iterator,其中it.col()it.row()允许检索当前元素的位置。 为了说明,arma::sp_mat iterator documentation)中给出的示例为:

sp_mat X = sprandu<sp_mat>(1000,2000,0.1);

sp_mat::const_iterator it     = X.begin();
sp_mat::const_iterator it_end = X.end();

for (; it != it_end; ++it) {
  cout << "val: " << (*it)    << endl;
  cout << "row: " << it.row() << endl;  // only available for arma::sp_mat,not arma::mat
  cout << "col: " << it.col() << endl;  // only available for arma::sp_mat,not arma::mat
}

当然,有许多变通方法可以获取arma::mat迭代的元素位置,最直接的方法可能是:

  • 在行和列的大小上使用嵌套for循环。
  • 使用单个for循环,并使用矩阵大小将迭代次数转换为行和列索引。
  • 某种形式的“压缩”迭代,对象包含或计算相应的索引。

但是,这些对我来说似乎很hacky且容易出错,因为它们需要处理矩阵大小,甚至需要手动处理索引。 我正在寻找更清洁的(也许是内部优化的)解决方案。在我看来,应该应该是实现这一目标的一种方法...

除了用于arma::sp_mat的解决方案之外,其他对我来说这样的“不错”的解决方案将使用.imbue.for_each,但函子不仅接受元素的当前值,而且接受还将其位置作为附加参数;目前看来这不可能。

解决方法

您似乎已经回答了自己的问题。我希望armadillo为我们提供了.imbue方法重载,该方法重载函数的函子数量与armadillo对象的维数相同,但目前它仅接受不带参数的函子。然后(我认为)可能是最简单的选择是使用lambda捕获必要的信息,例如下面的代码

    arma::umat m(3,3);
    {
        int i = 0;
        m.imbue([&i,num_rows = m.n_rows,num_cols = m.n_cols]() {
            arma::uvec sub = arma::ind2sub(arma::SizeMat{num_rows,num_cols},i++);
            return 10 * (sub[0] + 1) + sub[1];
        });
    }

在此示例中,每个元素的计算方式是其行索引加其列索引的10倍。我在这里捕获ì是线性索引,并将它以及lambda放在大括号内以界定其范围。

我也希望我可以写类似auto [row_idx,col_idx] = arma::ind2sub( ... )的东西,但是不幸的是ind2sub返回的内容不适用于结构化绑定。

如果愿意,还可以通过const引用捕获m并将arma::size(m)用作arma::ind2sub的第一个参数。

,

查看犰狳的源代码,row_col_iterator提供每个元素的行和列索引。它的工作方式类似于稀疏矩阵迭代器,但不会跳过零。修改代码:

mat X(10,10,fill::randu);

mat::const_row_col_iterator it     = X.begin_row_col();
mat::const_row_col_iterator it_end = X.end_row_col();

for (; it != it_end; ++it) {
  cout << "val: " << (*it)    << endl;
  cout << "row: " << it.row() << endl;
  cout << "col: " << it.col() << endl;
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...