如何使用 Eigen 在 Matrix 块上构造一个方便的迭代器
How to construct a convenient iterator over blocks of Matrix using Eigen
我想构建一个“按块列”迭代器,它遍历具有特征的密集矩阵的所有可能块。
#include <iostream>
#include <Eigen/Dense>
int main() {
Eigen::MatrixXd A(4,4);
A << 1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16;
for (Eigen::Index k=0; k< ? ; ++k) {
//?????
Eigen::Iterator it.... ;
std::cout<<it<<std::endl;
}
}
输出应该是:
1 2
5 6
9 10
13 14
3 4
7 8
11 12
15 16
基本上,我正在搜索
的一个不错的版本
#include <iostream>
#include <Eigen/Dense>
int main() {
Eigen::MatrixXd A(4,4);
A << 1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16;
int numberOfBlocksPerDir =2;
for (int i = 0; i < numberOfBlocksPerDir ; i++) {
for (int j = 0; j < numberOfBlocksPerDir ; j++) {
Eigen::Block<Eigen::MatrixXd, 2, 2> currentBlock = A.block<2, 2>(numberOfBlocksPerDir * j, numberOfBlocksPerDir * i);
std::cout<<currentBlock <<std::endl;
}
}
}
是否可以使用 Eigen 内置函数实现类似的功能?如果不是,我自己完成这个的好方法是什么? (定义我自己的迭代器?)
我在 Eigen
文档中找不到任何内容,但是一个简单的前向迭代器不需要太多:
- 等式运算符
- 增量运算符
- 取消引用运算符
这是我想出来的
template <Eigen::Index RowSize, Eigen::Index ColSize>
struct EigenBlockIt {
using Self = EigenBlockIt<RowSize, ColSize>;
// constructors for end()/begin() equivalents
EigenBlockIt() : matrix(nullptr) , col(0), row(0) { }
EigenBlockIt(const Eigen::MatrixXd& matrix) : matrix(&matrix) , col(0), row(0) { }
// comparison
friend bool operator ==(const Self& lhs, const Self& rhs) {
return lhs.matrix == rhs.matrix && lhs.row == rhs.row && lhs.col == rhs.col;
}
friend bool operator !=(const Self& lhs, const Self& rhs) {
return lhs.matrix != rhs.matrix || lhs.row != rhs.row || lhs.col != rhs.col;
}
// increment (postfix/prefix)
Self& operator++() {
row++;
if (row >= matrix->rows() / RowSize) {
row = 0;
col++;
if (col >= matrix->cols() / ColSize) {
matrix = nullptr;
row = 0;
col = 0;
}
}
return *this;
}
Self operator++(int) {
EigenBlockIt it = *this;
++(*this);
return it;
}
// dereference
const Eigen::Block<const Eigen::MatrixXd, RowSize, ColSize> operator *() const {
return matrix->block<RowSize, ColSize>((matrix->rows() / RowSize) * row, (matrix->cols() / ColSize) * col);
}
const Eigen::MatrixXd* matrix;
Eigen::Index row;
Eigen::Index col;
};
用法:
for (auto it = EigenBlockIt<2, 2>(A); it != EigenBlockIt<2, 2>(); ++it) {
std::cout << *it << std::endl;
}
我想构建一个“按块列”迭代器,它遍历具有特征的密集矩阵的所有可能块。
#include <iostream>
#include <Eigen/Dense>
int main() {
Eigen::MatrixXd A(4,4);
A << 1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16;
for (Eigen::Index k=0; k< ? ; ++k) {
//?????
Eigen::Iterator it.... ;
std::cout<<it<<std::endl;
}
}
输出应该是:
1 2
5 6
9 10
13 14
3 4
7 8
11 12
15 16
基本上,我正在搜索
的一个不错的版本#include <iostream>
#include <Eigen/Dense>
int main() {
Eigen::MatrixXd A(4,4);
A << 1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16;
int numberOfBlocksPerDir =2;
for (int i = 0; i < numberOfBlocksPerDir ; i++) {
for (int j = 0; j < numberOfBlocksPerDir ; j++) {
Eigen::Block<Eigen::MatrixXd, 2, 2> currentBlock = A.block<2, 2>(numberOfBlocksPerDir * j, numberOfBlocksPerDir * i);
std::cout<<currentBlock <<std::endl;
}
}
}
是否可以使用 Eigen 内置函数实现类似的功能?如果不是,我自己完成这个的好方法是什么? (定义我自己的迭代器?)
我在 Eigen
文档中找不到任何内容,但是一个简单的前向迭代器不需要太多:
- 等式运算符
- 增量运算符
- 取消引用运算符
这是我想出来的
template <Eigen::Index RowSize, Eigen::Index ColSize>
struct EigenBlockIt {
using Self = EigenBlockIt<RowSize, ColSize>;
// constructors for end()/begin() equivalents
EigenBlockIt() : matrix(nullptr) , col(0), row(0) { }
EigenBlockIt(const Eigen::MatrixXd& matrix) : matrix(&matrix) , col(0), row(0) { }
// comparison
friend bool operator ==(const Self& lhs, const Self& rhs) {
return lhs.matrix == rhs.matrix && lhs.row == rhs.row && lhs.col == rhs.col;
}
friend bool operator !=(const Self& lhs, const Self& rhs) {
return lhs.matrix != rhs.matrix || lhs.row != rhs.row || lhs.col != rhs.col;
}
// increment (postfix/prefix)
Self& operator++() {
row++;
if (row >= matrix->rows() / RowSize) {
row = 0;
col++;
if (col >= matrix->cols() / ColSize) {
matrix = nullptr;
row = 0;
col = 0;
}
}
return *this;
}
Self operator++(int) {
EigenBlockIt it = *this;
++(*this);
return it;
}
// dereference
const Eigen::Block<const Eigen::MatrixXd, RowSize, ColSize> operator *() const {
return matrix->block<RowSize, ColSize>((matrix->rows() / RowSize) * row, (matrix->cols() / ColSize) * col);
}
const Eigen::MatrixXd* matrix;
Eigen::Index row;
Eigen::Index col;
};
用法:
for (auto it = EigenBlockIt<2, 2>(A); it != EigenBlockIt<2, 2>(); ++it) {
std::cout << *it << std::endl;
}