Eigen sub-matrix operation (block)

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/qq_27251141/article/details/90442072

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

Guess you like

Origin blog.csdn.net/qq_27251141/article/details/90442072