[C + +] Eigen introduction to dense matrix 2 - Array operation

reference resources: https://blog.csdn.net/whereismatrix/article/details/104400205?spm=1001.2014.3001.5501

brief introduction

In Eigen, there are Matrix and vector for linear algebra related operations, but it is also necessary to perform related operations on the coefficients in the Matrix, which is a normal functional requirement. The Array class in Eigen meets this requirement.

Array definition

Similar to the Matrix and Vector described earlier, the Array class is also a template class.
The special point is that Array has one-dimensional Array and multi-dimensional Array.

  • The convenient and simple name of a one-dimensional array, such as ArrayNt, where N is the size of the array in the dimension and t is the coefficient data type.
  • Two dimensional array shape, such as ArrayNNt.

Example:

typetypedef
Array<float,Dynamic,1>ArrayXf
Array<float,3,1>Array3f
Array<double,Dynamic,Dynamic>ArrayXXd
Array<double,3,3>Array33d

Access and operation of array coefficients

For example, in Matrix, the overloaded bracket operator () is used to access the coefficients in the array. It can be used to take values or assign values. As you can see in the code, you can also use operator < < to initialize an array.

Example:

// array_1.cpp
#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;

int main()
{
  ArrayXXf  m(2,2);
  
  // assign some values coefficient by coefficient
  m(0,0) = 1.0; m(0,1) = 1.1;
  m(1,0) = 2.0; m(1,1) = m(0,1) + m(1,0);
  
  // print values to standard output
  cout << m << endl << endl;
 
  // using the comma-initializer is also allowed
  m << 2.0,3.0,
       8.0,9.0;
     
  // print values to standard output
  cout << m << endl;
}

Execution:

$ g++   -I /usr/local/include/eigen3 array_1.cpp -o array_1
$ ./array_1 
  1 1.1
  2 3.1

2 3
8 9

Addition and subtraction

Array overloads operator +, operator -, and can add or subtract two arrays. Of course, the two arrays must have the same Size, which is easy to understand.
It also implements a calculation: array + scalar. This adds scalars to each array element.

Example:

// array_2.cpp
#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;

int main()
{
  ArrayXXf a(3,3);
  ArrayXXf b(3,3);

  a << 1,2,3,
       4,5,6,
       7,8,9;
  
  b << 1,2,3,
       1,2,3,
       1,2,3;
  cout<<"array a:" << endl << a <<endl;
  cout<<"array b:" << endl << b <<endl;    
  // array +/- array
  cout << "a + b = " << endl << a + b << endl << endl;
  
  // array - scalar
  cout << "a - 1 = " << endl << a - 1 << endl;
}

Execution:

$ g++   -I /usr/local/include/eigen3 array_2.cpp -o array_2
$ 
$ ./array_2
array a:
1 2 3
4 5 6
7 8 9
array b:
1 2 3
1 2 3
1 2 3
a + b = 
 2  4  6
 5  7  9
 8 10 12

a - 1 = 
0 1 2
3 4 5
6 7 8

Multiplication

There are two types of multiplication: array * scalar and array * array. Array * scalar is the same as matrix; Array * array is an array coefficient oriented operation, which multiplies the matched coefficients. Only two arrays with the same dimension can be multiplied.

Example:

//array_multi.cpp

#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;

int main()
{
  ArrayXXf a(2,2);
  ArrayXXf b(2,2);

  a << 1,2,
       3,4;
  b << 5,6,
       7,8;
  
  cout<<"array a:" << endl << a <<endl;
  cout<<"array b:" << endl << b <<endl;    
  cout << "a * b = " << endl << a * b << endl;
  cout<< "a * 2 = " << endl << a * 2 << endl;
}

Execution:

$ g++   -I /usr/local/include/eigen3 array_multi.cpp -o array_multi
$
$ ./array_multi 
array a:
1 2
3 4
array b:
5 6
7 8
a * b = 
 5 12
21 32
a * 2 = 
2 4
6 8

Calculation of oriented coefficient

For array, in addition to the calculations of +, -, * mentioned above, these are oriented to array coefficients, and there are other function operations, such as:

  • The abs() method returns the absolute value of each element of the array;
  • The sqrt() method calculates the root of each element;
  • min(.): if you have two arrays with the same size, you can use the min() method to build a new array. The elements of the new array are the minimum value of the corresponding positions of the original two arrays.

Example:

//array_others.cpp

#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;

int main()
{
  ArrayXf a = ArrayXf::Random(5);
  a *= 2;
  cout << "a =" << endl 
       << a << endl;

  cout << "a.abs() =" << endl 
       << a.abs() << endl;

  cout << "a.abs().sqrt() =" << endl 
       << a.abs().sqrt() << endl;
       
  cout << "a.min(a.abs().sqrt()) =" << endl 
       << a.min(a.abs().sqrt()) << endl;
}

Execution:

$ g++   -I /usr/local/include/eigen3 array_others.cpp -o array_other
$ 
$ ./array_other 
a =
 -1.99997
 -1.47385
  1.02242
-0.165399
 0.131069
a.abs() =
 1.99997
 1.47385
 1.02242
0.165399
0.131069
a.abs().sqrt() =
  1.4142
 1.21402
 1.01115
0.406693
0.362034
a.min(a.abs().sqrt()) =
 -1.99997
 -1.47385
  1.01115
-0.165399
 0.131069

Direct conversion between Array and Matrix

In Eigen, Matrix is used for linear proxy calculation; While Array is used to operate on coefficients, they have different purposes.
The matrix class expression provides the. array() function method, which is used to convert the matrix into array expression, and then you can easily perform various operations on the coefficients. Correspondingly, array also provides. matrix(), which is used to get a matrix expression expression from array.
. array(),.matrix() can be used for both right and left values. However, in an expression, mixing. array(),.matrix() is not allowed. For example, you can't add a matrix and an array directly. However, it can be converted through. array(),.matrix(), and then calculated.

Because there are often such calculation requirements, Matrix in Eigen provides a convenient function cwiseProduct(Matrix) to handle Matrix.array() * Matrix.array() calculation, that is, cwiseProduct() method performs element level product (corresponding point multiplication) between matrices.

Example:

//array_matrix_1.cpp

#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;

int main()
{
  MatrixXf m(2,2);
  MatrixXf n(2,2);
  MatrixXf result(2,2);

  m << 1,2,
       3,4;
  n << 5,6,
       7,8;
  
  cout<<"array m:" << endl << m <<endl;
  cout<<"array n:" << endl << n <<endl<<"-----------------"<< endl;
  
  result = m * n;
  cout << "-- Matrix m*n: --" << endl << result << endl << endl;
  
  result = m.array() * n.array();
  cout << "-- Array m*n: --" << endl << result << endl << endl;
  
  result = m.cwiseProduct(n);
  cout << "-- With cwiseProduct: --" << endl << result << endl << endl;
  
  result = m.array() + 4;
  cout << "-- Array m + 4: --" << endl << result << endl << endl;
}

Execution:

$ g++   -I /usr/local/include/eigen3 array_matrix_1.cpp -o array_matrix_1
$
$ ./array_matrix_1 
array m:
1 2
3 4
array n:
5 6
7 8
-----------------
-- Matrix m*n: --
19 22
43 50

-- Array m*n: --
 5 12
21 32

-- With cwiseProduct: --
 5 12
21 32

-- Array m + 4: --
5 6
7 8

Tags: C++

Posted on Mon, 06 Dec 2021 19:28:30 -0500 by tenaki