Eigen中的块操作

Eigen块操作

在SLAM问题中的对于Hessian矩阵以及其他一些雅克比矩阵进行操作的时候,经常会使用到eigen库中矩阵的块操作,在此做一个简单的总结

Block

Eigen中最通用的就是Block,可以使用block来定位并取出各种位置和内容

对于一个\((p,q)\) 大小,从\((i,j)\)坐标开始的矩阵块,可以有以下两种表示的方式

1
2
matrix.block(i,j,p,q);
matrix.block<p,q>(i,j);

其中较为常用的就是第一种方式

可以使用block表达式作为右值,同时也可以用同样大小的block来作为左值进行赋值使用.

Row & Col

行和列是特殊的据真快,EIgen提供了特殊的用法

对于矩阵中的第i行

1
matrix.row(i);

对于矩阵中的第j列

1
matrix.col(j);

边角定位操作

对于边角的定位,也是matrix中至关重要的一个环节,也就是可以通过这种方式来修改矩阵的某一个部分

这个部分很好用

Corner

左上角的 p x q 大小的矩阵块

块操作Version constructing a dynamic-size block expressionVersion constructing a fixed-size block expression
左上角的 p x q 大小的矩阵块 *matrix.topLeftCorner(p,q);matrix.topLeftCorner<p,q>();
左下角的 p x q 大小的矩阵块 *matrix.bottomLeftCorner(p,q);matrix.bottomLeftCorner<p,q>();
右上角的 p x q 大小的矩阵块 *matrix.topRightCorner(p,q);matrix.topRightCorner<p,q>();
右下角的 p x q 大小的矩阵块 *matrix.bottomRightCorner(p,q);matrix.bottomRightCorner<p,q>();

Line

块操作Version constructing a dynamic-size block expressionVersion constructing a fixed-size block expression
包含前q行 *matrix.topRows(q);matrix.topRows();
包含后q行 *matrix.bottomRows(q);matrix.bottomRows();
包含前q列 *matrix.leftCols(p);matrix.leftCols
包含后q列 *matrix.rightCols(q);matrix.rightCols();

向量的块操作

对于vector也存在分块的操作

块操作Version constructing a dynamic-size block expressionVersion constructing a fixed-size block expression
包含前n个元素 *vector.head(n);vector.head();
包含后n个元素 *vector.tail(n);vector.head();
包含从i开始的n个元素 *vector.segment(i,n);vector.segment(i);

Example

Block

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <Eigen/Dense>
#include <iostream>
using namespace std;
int main()
{
Eigen::MatrixXf m(4,4);
m << 1, 2, 3, 4,
5, 6, 7, 8,
9,10,11,12,
13,14,15,16;
cout << "Block in the middle" << endl;
cout << m.block<2,2>(1,1) << endl << endl;

for (int i = 1; i <= 3; ++i)
{
cout << "Block of size " << i << "x" << i << endl;
cout << m.block(0,0,i,i) << endl << endl;
}
}

输出为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Block in the middle
6 7
10 11

Block of size 1x1
1

Block of size 2x2
1 2
5 6

Block of size 3x3
1 2 3
5 6 7
9 10 11

以上方式都是使用为右值,只读形式

Row & Col

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <Eigen/Dense>
#include <iostream>
using namespace std;
int main()
{
Eigen::MatrixXf m(3,3);
m << 1,2,3,
4,5,6,
7,8,9;
cout << "Here is the matrix m:" << endl << m << endl;
cout << "2nd Row: " << m.row(1) << endl;
m.col(2) += 3 * m.col(0);
cout << "After adding 3 times the first column into the third column, the matrix m is:\n";
cout << m << endl;
}

输出为

1
2
3
4
5
6
7
8
9
Here is the matrix m:
1 2 3
4 5 6
7 8 9
2nd Row: 4 5 6
After adding 3 times the first column into the third column, the matrix m is:
1 2 6
4 5 18
7 8 30

Corner & Line

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <Eigen/Dense>
#include <iostream>
using namespace std;
int main()
{
Eigen::Matrix4f m;
m << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10,11,12,
13,14,15,16;
cout << "m.leftCols(2) =" << endl << m.leftCols(2) << endl << endl;
cout << "m.bottomRows<2>() =" << endl << m.bottomRows<2>() << endl << endl;
m.topLeftCorner(1,3) = m.bottomRightCorner(3,1).transpose();
cout << "After assignment, m = " << endl << m << endl;
}

输出为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
m.leftCols(2) =
1 2
5 6
9 10
13 14

m.bottomRows<2>() =
9 10 11 12
13 14 15 16

After assignment, m =
8 12 16 4
5 6 7 8
9 10 11 12
13 14 15 16

Vector Block Operation

1
2
3
4
5
6
7
8
9
10
11
12
#include <Eigen/Dense>
#include <iostream>
using namespace std;
int main()
{
Eigen::ArrayXf v(6);
v << 1, 2, 3, 4, 5, 6;
cout << "v.head(3) =" << endl << v.head(3) << endl << endl;
cout << "v.tail<3>() = " << endl << v.tail<3>() << endl << endl;
v.segment(1,4) *= 2;
cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;
}

输出为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
v.head(3) =
1
2
3

v.tail<3>() =
4
5
6

after 'v.segment(1,4) *= 2', v =
1
4
6
8
10
6