Eigen库学习 ---- 4.块操作
上篇为:Eigen库学习 ---- 3.数组类和系数运算
本篇为这个链接的学习笔记。
块操作可以提取出矩阵的当中的一小块进行运算,可以作为左值,也可以作为右值。
一、使用块操作
块操作有两种表达方式:从(i,j)处提取pxq大小的矩阵块。
- matrix.block(i,j,p,q);(称为动态大小的块)
- matrix.block<p,q>(i,j); (称为固定大小的块)
固定大小的矩阵块执行的更快,但是需要编译器提前知道这个矩阵的大小。
例如:
MatrixXf m(4, 4);
m << 1,2,3,4,
5,6,7,8,
9,10,11,12,
13,14,15,16;
cout << "从(1,1)处取出2x2大小的矩阵。" << endl;
cout << m.block<2, 2>(1, 1) << endl << endl;
for (int i = 0; i <=3; i++)
{
cout << "Block of size" << i << "x" << i << endl;
cout << m.block(0, 0, i, i) << endl << endl;
}
输出结果如下:
从(1,1)处取出2x2大小的矩阵。
6 7
10 11
Block of size0x0
Block of size1x1
1
Block of size2x2
1 2
5 6
Block of size3x3
1 2 3
5 6 7
9 10 11
在上面的例子里,矩阵块是作为右值出现的,也可以作为左值出现进行赋值。
例如:
Array22f m;
m << 1,2,
3,4;
Array44f a = Array44f::Constant(0.6);
cout << "Here is the array a:" << endl << a << endl<<endl;
a.block<2, 2>(1, 1) = m;
cout << "Here is now a with m copied into its central 2x2 block:" << endl << a << endl << endl;
a.block(0, 0, 2, 3) = a.block(2, 1, 2, 3);
cout << "Here is now with bottom-right 2x3 block copied into top-left 2x3 block:" << endl << a << endl << endl;
输出结果如下:
Here is the array a:
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
0.6 0.6 0.6 0.6
Here is now a with m copied into its central 2x2 block:
0.6 0.6 0.6 0.6
0.6 1 2 0.6
0.6 3 4 0.6
0.6 0.6 0.6 0.6
Here is now with bottom-right 2x3 block copied into top-left 2x3 block:
3 4 0.6 0.6
0.6 0.6 0.6 0.6
0.6 3 4 0.6
0.6 0.6 0.6 0.6
二、列和行
单独的列和行是块的特殊情况。Eigen提供了一些方法来轻松处理他们:.col()和.row()。
例如:
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;
三、角相关的矩阵块
Eigen提供了特殊的方法来处理矩阵或数组某个角或边对齐的块,例如.topLeftCorner()可以用来引用矩阵左上角的块。
例如:
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;
输出结果如下:
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
四、向量的块操作
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;
//从第一个元素往后的4个元素都自乘2
cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;
输出结果如下:
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