遍历 arma::mat 并检索元素位置
Posted
技术标签:
【中文标题】遍历 arma::mat 并检索元素位置【英文标题】:Iterating over arma::mat and retrieving element locations 【发布时间】:2020-10-29 11:26:08 【问题描述】:我正在尝试按元素设置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
循环,并使用矩阵大小,将迭代次数转换为行和列索引。
某种形式的“压缩”迭代,对象包含或计算相应的索引。
然而, 这些对我来说似乎相当笨拙且容易出错,因为它们需要使用矩阵大小,甚至需要手动处理索引。 我正在寻找一种更简洁(可能是内部优化)的解决方案。我觉得应该有一种方法可以实现这一目标......
除了用于arma::sp_mat
的解决方案之外,对我来说,其他这样的“不错”解决方案将使用.imbue
或.for_each
,但使用的函子不仅接受元素的当前值,还接受其位置作为附加参数;目前这似乎是不可能的。
【问题讨论】:
【参考方案1】:查看犰狳源代码,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;
【讨论】:
这正是我要找的,感谢您深入研究源代码!它似乎至少从 9.900.x 开始就可用了——我想知道,为什么它不属于 official docs...【参考方案2】:您似乎已经自己回答了您的问题。我希望犰狳为我们提供了一个.imbue
方法重载,它接收了一个函子,其参数与犰狳对象的维度一样多,但目前它只接受一个没有参数的函子。那么可能最简单的选择(在我看来)是使用 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::SizeMatnum_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
的第一个参数。
【讨论】:
谢谢,我不知道arma::ind2sub
,它解决了我建议的变通办法的大部分问题。我想这回答了这个问题。 :) — 正如您似乎也希望这样的功能:您知道这是否故意丢失?如果没有,可能值得尝试实施并打开 MR ...
我不知道这是否是故意遗漏的。如果你有兴趣,你的犰狳似乎托管在gitlab。以上是关于遍历 arma::mat 并检索元素位置的主要内容,如果未能解决你的问题,请参考以下文章
(Rcpp, armadillo) 将 arma::vec 转换为 arma::mat
使用 std::nth_element 对 arma::mat 的行进行排序
使用 BeautifulSoup 遍历 html 树中的元素,并生成保持每个元素相对位置的输出?在 Python 中
javascript 循环遍历具有相同类的所有元素并更改子的位置