Article Directory
1, sub-matrix operations Introduction
Sub-matrix operations, also known as block operations, matrix operations, and extraction operation of the application sub-matrix is also very broad. Eigen therefore also provides a process related operations. Extracted sub-matrix may be used both as a left value during operation can also be used as a right value.
2, using the general method of operation of block
Eigen fast operation in the most basic operation is .block()
completed. Submatrix extracted into the same dynamic size and fixed size.
Block operation | Construction of dynamic sub-matrix size |
---|---|
Extraction block size (p, q), starting from (i, j) | matrix.block(i,j,p,q) |
Also note that in Eigen, the index is zero. All the operating method can be applied to the Array. Also the use of more fixed-size fast mode of operation on a small matrix operations, but must know at compile time required size of the matrix.
Here is an example:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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;
}
}
Execution results are as follows:
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
In the above example, .block()
it is applied to a left operation value, i.e. read data. In fact, it can also be used as the operation of the right value, i.e., write data may be entered. The following is an application example rvalue.
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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 a with bottom-right 2x3 block copied into top-left 2x2 block:"<<endl<<a<<endl<<endl;
}
Execution results are as follows:
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 a with bottom-right 2x3 block copied into top-left 2x2 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
.block()
Method is a very general block operation method. In addition to this general method, Eigen also provides a special function of some common special operations. In terms of speed point of view, you should provide more information as much as possible at compile time. For example, if you need to operate the block is a column, then you can use the .col()
function. Such Eigen can learn this information for further optimization.
The particular method of operation is summarized as follows.
3, the row and column sub subformulae of formula
We can use .col()
and .row()
methods to manipulate or extract a column or row.
Block operation | method |
---|---|
I-th row | matrix.row(i); |
J-th column | matrix.col(j); |
Here is an example:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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 third column,the matrix m is:\n";
cout<<m<<endl;
}
Execution results are as follows:
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 third column,the matrix m is:
1 2 6
4 5 18
7 8 30
4, corner submatrix
Eigen provides a method to extract sub-matrices start from the corners, such as .topLeftCorner()
indicating the start sub-matrix extracted from the upper left corner. These operations are summarized as follows:
Block operation | Dynamic Matrix version | Fixed matrix version |
---|---|---|
The upper left corner pxq | matrix.topLeftCorner(p,q); |
matrix.topLeftCorner<p,q>(); |
The lower left corner pxq | matrix.bottomLeftCorner(p,q); |
matrix.bbottomLeftCorner<p,q>(); |
The upper right corner pxq | matrix.topRightCorner(p,q); |
matrix.topRightCorner<p,q>(); |
The lower right corner pxq | matrix.bottomRightCorner(p,q); |
matrix.bottomRightCorner<p,q>(); |
Front line p | matrix.topRows(p); |
matrix.topRows<p>(); |
After the line p | matrix.bottomRows(p); |
matrix.bottomRows<p>(); |
Q front row | matrix.leftCols(q); |
matrix.leftCols<q>(); |
After the column q | matrix.rightCols(q); |
matrix.rightCols<q>(); |
Here is an example:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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;
}
Execution results are as follows:
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
5, the operation of the sub-vector of the vectors
Eigen vectors are also to provide some type of sub-operating method, summarized as follows:
Block operation | Vector version fixed | Dynamic vector version |
---|---|---|
The first n elements | vector.head(n); | vector.head(); |
After n elements | vector.tail(n); | vector.tail(); |
Start n elements taken from i | vector.segment(i,n) | vector.segment(i); |
Explain again, all operations on the matrix also applies to Array, all operations on the column vectors also apply to a row vector.
Here is an example:
#include <iostream>
#include "Eigen/Dense"
using namespace std;
using namespace Eigen;
int main()
{
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;
}
Execution results are as follows:
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