Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/cplusplus11/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++11 特征矩阵上的Foreach循环?_C++11_Foreach_Eigen - Fatal编程技术网

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()获取数据数组的大小 使用这两个,我们现在有了指

是否可以将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()
获取数据数组的大小

使用这两个,我们现在有了指向数组第一个元素和结尾的指针,分别是
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版)