0%

块操作

本章介绍 Matrix 和 Array 中的块操作。

块操作 .block()

取一个从 (i,j) 开始的,大小为 (p,q) 的块,有两种语法:

  • matrix.block(i,j,p,q); => 构造一个动态大小的块
  • matrix.block<p,q>(i,j); => 构造一个固定大小的块

两种语法的执行结果相同,都能用在固定大小/动态大小的矩阵/数组上。唯一不同的是当块大小已知且比较小的时候,返回固定大小的块能让代码执行得更快一点。

尽管 .block() 方法可以用于任何块操作,但对于特殊情况,使用更具针对性的方法能提供更好的性能,下面将介绍三种特殊方法。

行列操作

  • 取第 i 行:matrix.row(i)
  • 取第 j 列:matrix.col(j)

与角相关的操作

同样也有返回动态大小/固定大小两种语法

  • 左上角 p*qmatrix.topLeftCorner(p,q); matrix.topLeftCorner<p,q>();
  • 左下角 p*qmatrix.bottomLeftCorner(p,q); matrix.bottomLeftCorner<p,q>();
  • 右上角 p*qmatrix.topRightCorner(p,q); matrix.topRightCorner<p,q>();
  • 右下角 p*qmatrix.bottomRightCorner(p,q); matrix.bottomRightCorner<p,q>();
  • 取前 q 行:matrix.topRows(q); matrix.topRows<q>();
  • 取后 q 行:matrix.bottomRows(q); matrix.bottomRows<q>();
  • 取前 p 列:matrix.leftCols(p); matrix.leftCols<p>();
  • 取后 p 列:matrix.rightCols(q); matrix.rightCols<q>();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

对向量和一维数组的块操作

同样也有返回动态大小/固定大小两种语法

  • 包含前 n 个元素:vector.head(n); vector.head<n>();
  • 包含后 n 个元素:vector.tail(n); vector.tail<n>();
  • i 开始,包含 n 个元素:vector.segment(i,n); vector.segment<n>(i);
1
2
3
4
5
6
7
8
9
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
18
	
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