简体   繁体   English

C ++ Armadillo:使用迭代器的double for循环

[英]C++ Armadillo: double for loop using iterators

What is the best way to use iterators in double for-loops. 在双for循环中使用迭代器的最佳方法是什么。 For a single loop, the obvious way seems to be: 对于单个循环,显而易见的方法似乎是:

arma::vec test = arma::ones(10);
for(arma::vec::iterator i = test.begin(); i != test.end(); ++i){
   int one = *i;
}

So I want to transform the following: 所以我要转换以下内容:

arma::mat test = arma::ones(10,10);
for (int i = 0; i < test.n_rows; i++){
 for (int j = 0; j < test.n_cols; j++){
  int one = test(i,j);
 }
}

to use iterators instead of integer indices. 使用迭代器而不是整数索引。 Thanks for any advice. 感谢您的任何建议。

It's recommended to still use a single loop when accessing elements in a matrix. 当访问矩阵中的元素时,建议仍然使用单个循环。 Armadillo stores data in column-major format (for compatibility with LAPACK), so the iterator will travel along each column in the matrix. Armadillo以列主格式存储数据(为了与LAPACK兼容),因此迭代器将沿着矩阵中的每一列行进。

arma::mat A(4, 5, arma::fill::randu);
A.print("A:");

// C++98 

arma::mat::iterator it_end = A.end();

for(arma::mat::iterator it = A.begin(); it != it_end; ++it)
   {
   std::cout << (*it) << std::endl;
   }

// C++11

for(const auto& val : A)
   {
   std::cout << val << std::endl;
   }

If you really want to use a double loop, use .begin_col() and .end_col() : 如果您确实想使用双循环,请使用.begin_col().end_col()

// C++11

for(arma::uword c=0; c < A.n_cols; ++c)
  {
  auto it_end = A.end_col(c);

  for(auto it = A.begin_col(c); it != it_end; ++it)
    {
    std::cout << (*it) << std::endl;
    }
  }

Lastly, the .for_each() function is an alternative to using iterators: 最后, .for_each()函数是使用迭代器的替代方法:

 // C++11

 A.for_each( [](arma::mat::elem_type& val) { std::cout << val << std::endl; } );

Three things come to mind, and not just to double iterations, but to any kind of iteration (just apply everything below twice...) 我想到了三件事,不仅是两次迭代,还包括任何形式的迭代(只需将下面的所有内容应用两次...)

1) If the container's contents do not change during the loop, call end() once and save it, and compare the iterator to the saved value on each iteration of the loop. 1)如果容器的内容在循环期间没有更改,请调用一次end()并保存它,并在循环的每次迭代中将迭代器与保存的值进行比较。

Not so good: 不太好:

for(arma::vec::iterator i = test.begin(); i != test.end(); ++i)

As written, end() is being technically called at each loop's iteration, and its return value is being compared to the current value of the loop iterator. 如所写,在每个循环的迭代中都会从技术上调用end(),并将其返回值与循环迭代器的当前值进行比较。

2) 2)

Better: 更好:

const arma::vec::iterator e=test.end();

for(arma::vec::iterator i = test.begin(); i != e; ++i)

This has a far better chance of getting optimized, especially with a const qualifier (although the compiler will likely be able to figure it out on its own, if e never gets modified, anyway). 这有得到优化,尤其是一个const限定符一个更好的机会(尽管编译器将有可能能够弄清楚自身,如果e永远不会被修改,反正)。

3) 3)

Best: 最好:

for(const auto &value:test)

The C++11 iteration syntax tells the compiler exactly what's going on, giving the compiler the best opportunity to employ all container iteration tricks it's been programmed to know about. C ++ 11迭代语法告诉编译器确切的操作信息,从而为编译器提供了最佳机会来利用已被编程了解的所有容器迭代技巧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM