C++11 特征矩阵上的Foreach循环?
是否可以将C++11的foreach语法用于特征矩阵?例如,如果我想计算一个矩阵的和(我知道有一个内置函数,我只想要一个简单的例子),我想做如下的事情C++11 特征矩阵上的Foreach循环?,c++11,foreach,eigen,C++11,Foreach,Eigen,是否可以将C++11的foreach语法用于特征矩阵?例如,如果我想计算一个矩阵的和(我知道有一个内置函数,我只想要一个简单的例子),我想做如下的事情 Matrix2d a; a << 1, 2, 3, 4; double sum = 0.0; for(double d : a) { sum += d; } Matrix2d a; a可以使用成员函数.data()获得指向矩阵数据数组的指针 还可以使用成员函数.size()获取数据数组的大小 使用这两个,我们现在有了指
Matrix2d a;
a << 1, 2,
3, 4;
double sum = 0.0;
for(double d : a) {
sum += d;
}
Matrix2d a;
a可以使用成员函数.data()
获得指向矩阵数据数组的指针
还可以使用成员函数.size()
获取数据数组的大小
使用这两个,我们现在有了指向数组第一个元素和结尾的指针,分别是a.data()
和a.data()+a.size()
另外,我们知道可以使用迭代器(在我们的例子中是数组指针)初始化std::vector
因此,我们可以获得一个双精度向量,它用std::vector(a.data(),a.data()+a.size())
包装矩阵元素
此向量可与代码段中包含的基于范围的for循环语法一起使用,如下所示:
Matrix2d a;
a << 1, 2,
3, 4;
double sum = 0.0;
for(double d : std::vector<double>(a.data(), a.data()+a.size())) {
sum += d;
}
Matrix2d a;
基于范围的for循环需要在该类型上实现方法.begin()
和.end()
,它们不适用于特征矩阵。然而,指针也是C++中一种有效的随机访问迭代器,所以方法>代码> >数据> <代码> >数据(+).siz()/c>可以用于任何STL算法的开始和结束功能。 对于您的特定情况,更有效地获得起始和结束迭代器,并将两个迭代器传递给标准算法:
auto const sum = std::accumulate(a.data(), a.data()+a.size(), 0.0);
如果您有另一个函数确实需要对
使用基于范围的,则需要在与类型相同的命名空间中提供begin()
和end()
的实现(用于参数相关的查找)。这里我将使用C++14来保存键入:
namespace Eigen
{
auto begin(Matrix2d& m) { return m.data(); }
auto end(Matrix2d& m) { return m.data()+m.size(); }
auto begin(Matrix2d const& m) { return m.data(); }
auto end(Matrix2d const& m) { return m.data()+m.size(); }
}
STL风格的迭代器支持已添加到3.4版的Eigen中
看
对于OP的问题,您可以执行以下操作:
Matrix2d A;
A << 1, 2,
3, 4;
double sum = 0.0;
for(auto x : A.reshaped())
sum += x;
Matrix2d A;
A这将执行矩阵的副本,而不是迭代矩阵本身,可能不是询问者想要做的事情。基于范围的for
循环是否需要不合格的开始(A)
/结束(A)
?那么这些不需要在全局名称空间或Eigen
名称空间(由ADL找到)中吗?是的@Ben,我认为你是对的(并且不执行非参数相关的查找)。知道为什么Eigen不提供这些吗?可能只是因为没有人编写过它。也许项目会欢迎一个合适的补丁?或者至少是错误报告。此方法不考虑矩阵跨步:.begin()
和end()
可以作为成员或自由函数(使用ADL找到)实现。此方法不考虑矩阵跨步:。这可能会导致一些不必要的副作用,如未初始化值的浮点操作等。是的,您是对的,它没有考虑跨步,使用基类型时可能会很危险。我刚刚读了一些书,似乎从v3.4(还不稳定)开始,Eigen将支持迭代器-不幸的是,仅从3.3.9版开始,目前还不稳定(目前,我依赖于3.3.7版)